1. 프로젝트 설정 (build.gradle)
웹 API와 DB 연동을 위해 필요한 기본 의존성입니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
2. 설정 파일 (src/main/resources/application.yml)
H2 데이터베이스와 JPA 콘솔 설정입니다.
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create-drop # 실행 시 테이블 자동 생성 및 종료 시 삭제
show-sql: true
properties:
hibernate:
format_sql: true
h2:
console:
enabled: true # 브라우저에서 H2 콘솔 접근 허용 (http://localhost:8080/h2-console)
3. 도메인 / 엔티티 클래스 (Item.java)
데이터베이스에 저장될 데이터를 정의하는 엔티티입니다.
package com.example.demo.domain;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter @Setter
@NoArgsConstructor
@Table(name = "items")
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer price;
private Integer stockQuantity;
public Item(String name, Integer price, Integer stockQuantity) {
this.name = name;
this.price = price;
this.stockQuantity = stockQuantity;
}
}
4. 레포지토리 인터페이스 (ItemRepository.java)
스프링 데이터 JPA를 활용해 기본 CRUD 쿼리를 자동으로 처리해 주는 인터페이스입니다.
package com.example.demo.repository;
import com.example.demo.domain.Item;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ItemRepository extends JpaRepository<Item, Long> {
}
5. 서비스 클래스 (ItemService.java)
비즈니스 로직을 처리하는 계층입니다.
package com.example.demo.service;
import com.example.demo.domain.Item;
import com.example.demo.repository.ItemRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ItemService {
private final ItemRepository itemRepository;
// C: 생성 (Create)
@Transactional
public Item createItem(Item item) {
return itemRepository.save(item);
}
// R: 전체 조회 (Read - List)
public List<Item> getAllItems() {
return itemRepository.findAll();
}
// R: 단건 조회 (Read - Detail)
public Item getItemById(Long id) {
return itemRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("해당 아이템이 없습니다. id=" + id));
}
// U: 수정 (Update)
@Transactional
public Item updateItem(Long id, Item requestItem) {
Item item = getItemById(id);
item.setName(requestItem.getName());
item.setPrice(requestItem.getPrice());
item.setStockQuantity(requestItem.getStockQuantity());
return item;
}
// D: 삭제 (Delete)
@Transactional
public void deleteItem(Long id) {
Item item = getItemById(id);
itemRepository.delete(item);
}
}
6. 컨트롤러 클래스 (ItemController.java)
클라이언트와 HTTP 요청/응답을 주고받는 REST API 엔드포인트입니다.
package com.example.demo.controller;
import com.example.demo.domain.Item;
import com.example.demo.service.ItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/items")
@RequiredArgsConstructor
public class ItemController {
private final ItemService itemService;
// 1. 등록 (POST)
@PostMapping
public ResponseEntity<Item> createItem(@RequestBody Item item) {
Item createdItem = itemService.createItem(item);
return ResponseEntity.status(HttpStatus.CREATED).body(createdItem);
}
// 2. 전체 조회 (GET)
@GetMapping
public ResponseEntity<List<Item>> getAllItems() {
List<Item> items = itemService.getAllItems();
return ResponseEntity.ok(items);
}
// 3. 단건 조회 (GET)
@GetMapping("/{id}")
public ResponseEntity<Item> getItemById(@PathVariable Long id) {
Item item = itemService.getItemById(id);
return ResponseEntity.ok(item);
}
// 4. 수정 (PUT)
@PutMapping("/{id}")
public ResponseEntity<Item> updateItem(@PathVariable Long id, @RequestBody Item item) {
Item updatedItem = itemService.updateItem(id, item);
return ResponseEntity.ok(updatedItem);
}
// 5. 삭제 (DELETE)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteItem(@PathVariable Long id) {
itemService.deleteItem(id);
return ResponseEntity.noContent().build();
}
}
API 테스트 방법 (cURL 예시)
서버를 실행(java -jar 또는 IDE에서 Run)한 뒤, 아래 명령어로 테스트할 수 있습니다.
1. 아이템 생성 (POST)
curl -X POST http://localhost:8080/api/items \
-H "Content-Type: application/json" \
-d '{"name": "스프링 부트 책", "price": 25000, "stockQuantity": 100}'
2. 전체 조회 (GET)
curl -X GET http://localhost:8080/api/items
3. 단건 조회 (GET)
curl -X GET http://localhost:8080/api/items/1
4. 수정 (PUT)
curl -X PUT http://localhost:8080/api/items/1 \
-H "Content-Type: application/json" \
-d '{"name": "스프링 부트 개정판", "price": 28000, "stockQuantity": 50}'
5. 삭제 (DELETE)
curl -X DELETE http://localhost:8080/api/items/1
빌드
방법 1: Gradle 탭(Tool Window) 사용하기 (가장 추천)
인텔리제이 화면 오른쪽(또는 왼쪽 하단)에 있는 Gradle 패널을 이용하는 가장 직관적인 방법입니다.
- Gradle 탭 열기
- 인텔리제이 우측 상단이나 하단에 있는 Gradle 아이콘을 클릭합니다.
- 빌드 태스크 실행하기
- 패널 창이 열리면 아래 경로로 찾아 들어갑니다.
- 프로젝트 이름 > Tasks > build > bootJar (또는 build)
- bootJar를 더블클릭하거나, 우클릭 후 Run '...bootJar'를 클릭합니다.
- JAR 파일 확인하기
- 빌드가 성공적으로 끝나면 프로젝트 내부에 아래 경로로 JAR 파일이 생성됩니다.
- 위치: 프로젝트 폴더/build/libs/파일명-0.0.1-SNAPSHOT.jar
방법 2: 인텔리제이 터미널(Terminal) 사용하기
명령어 창에 익숙하시다면 인텔리제이 하단의 Terminal 탭에서 Gradle 명령어를 직접 입력할 수 있습니다.
- 인텔리제이 하단 메뉴에서 Terminal을 엽니다.
- 운영체제에 맞는 빌드 명령어를 입력합니다.
- Windows: gradlew.bat bootJar 또는 gradlew bootJar
- Mac / Linux: ./gradlew bootJar
- 빌드가 완료되면 방법 1과 마찬가지로 build/libs/ 폴더에 JAR 파일이 생성됩니다.
💡 생성된 JAR 파일 실행해보기
빌드가 완료되었다면 터미널에서 아래 명령어로 직접 실행해 볼 수 있습니다.
cd build/libs
java -jar 파일명-0.0.1-SNAPSHOT.jar
http://localhost:8080 접속 테스트