1) 프로젝트 만들기
application.properties
server.port=80
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shop?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.show_sql=true
#콘솔창에 출력되는 쿼리를 가독성 좋게 포맷팅
spring.jpa.properties.hibernate.format_sql=true
#쿼리에 물음표로 출력되는 바인드 파라미터 출력
logging.level.org.hibernate.type.descriptor.sql=trace
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
애플리케이션 구동 시 JPA의 데이터베이스 초기화 전략을 설정할 수 있다.
none : 사용하지 않음
create : 기존 테이블 삭제 후 테이블 생성
create-drop : 기존 테이블 삭제 후 테이블 생성, 종료 시점에 테이블 삭제
update : 변경된 스키마 적용
validate ; 엔티티와 테이블 정상 맵핑 확인
* update 옵션에서 컬럼 삭제는 엄청난 문제를 발생할 수 있기 때문에 컬럼 추가만 반영된다.
개발 초기에는 편의상 create 또는 update를 이용하지만 추후에는 꼭 validate 옵션으로 설정해야한다.
spring.jpa.hibernate.ddl-auto=create
ItemSellStatus와 Item 을 아래와 같이 생성
ItemSellStatus.java
package com.shop.constant;
public enum ItemSellStatus {
SELL, SOLD_OUT
}
Item.java
package com.shop.entity;
import com.shop.constant.ItemSellStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "item")
@Getter
@Setter
@ToString
public class Item {
@Id
@Column(name = "item_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id; // 상품코드
@Column(nullable = false, length = 50)
private String itemNm; // 상품명
@Column(name = "price", nullable = false)
private int price; // 상품가격
@Column(nullable = false)
private int stockNumber; // 재고수량
@Lob
@Column(nullable = false)
private String itemDetail; // 상품상세설명
@Enumerated(EnumType.STRING)
private ItemSellStatus itemSellStatus; // 상품판매상태
private LocalDateTime regTime; // 등록시간
private LocalDateTime updateTime; // 수정시간
}
구동시 결과
Hibernate:
drop table if exists hibernate_sequence
Hibernate:
drop table if exists item
Hibernate:
create table hibernate_sequence (
next_val bigint
) engine=InnoDB
Hibernate:
insert into hibernate_sequence values ( 1 )
Hibernate:
create table item (
item_id bigint not null,
item_detail longtext not null,
item_nm varchar(50) not null,
item_sell_status varchar(255),
price integer not null,
reg_time datetime(6),
stock_number integer not null,
update_time datetime(6),
primary key (item_id)
) engine=InnoDB
Repository
Spring Data JPA에서는 엔티티 매니저를 직접 이용해 코드를 작성하지 않아도 된다. 그 대신에 Data Access Object의 역할을 하는 Repository 인터페이스를 설계한 후 사용하는 것만으로 충분하다.
JpaRepository는 기본적인 CRUD 및 페이징 처리를 위한 메소드가 정의되어 있다.
package com.shop.repository;
import com.shop.entity.Item;
import org.springframework.data.jpa.repository.JpaRepository;
// extends JpaRepository<엔티티 타입 클래스, 기본기 타입>
public interface ItemRepository extends JpaRepository<Item, Long> {
}
테스트 하기위해
application-test.properties 생성하여 h2 데이터베이스를 연결한다.
server.port=80
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.properties.hibernate.show_sql=true
#콘솔창에 출력되는 쿼리를 가독성 좋게 포맷팅
spring.jpa.properties.hibernate.format_sql=true
#쿼리에 물음표로 출력되는 바인드 파라미터 출력
logging.level.org.hibernate.type.descriptor.sql=trace
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
해당 인터페이스에서 아래와 같이 클릭하면 손쉽게 테스트 클래스를 만들수 있다.
테스트가 있는 경우 표시되며 따로 생성도 가능하다.
package com.shop.repository;
import com.shop.constant.ItemSellStatus;
import com.shop.entity.Item;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import java.time.LocalDateTime;
@SpringBootTest
@TestPropertySource(locations = "classpath:application-test.properties")
public class ItemRepositoryTest {
@Autowired
ItemRepository itemRepository;
@Test
@DisplayName("상품 저장 테스트")
public void createItemTest(){
Item item = new Item();
item.setItemNm("테스트 상품");
item.setPrice(1000);
item.setItemDetail("상세설명");
item.setItemSellStatus(ItemSellStatus.SELL);
item.setStockNumber(100);
item.setRegTime(LocalDateTime.now());
item.setUpdateTime(LocalDateTime.now());
Item saveItem = itemRepository.save(item);
System.out.println(saveItem.toString());
}
}
결과
* 따로 insert문 작성하지 않았는데도 자동으로 쿼리문이 생성이 되었다.
그러므로 Spring Data JPA는 인터페이스만 작성하면 런타임 시점에 자바의 Dynamic Proxy를 이용해서 객체를 동적으로 생성해준다. 또한 Data Access Object(Dao)와 xml 파일에 쿼리문을 작성하지 않아도 된다.
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
item
(item_detail, item_nm, item_sell_status, price, reg_time, stock_number, update_time, item_id)
values
(?, ?, ?, ?, ?, ?, ?, ?)
'2022 > JPA입문(完)' 카테고리의 다른 글
스프링 시큐리티 - 1 (0) | 2022.01.23 |
---|---|
Thymeleaf - 1 (0) | 2022.01.21 |
Spring Data JPA - 2 (0) | 2022.01.20 |
Spring Data JPA - 1 (0) | 2022.01.18 |
개발환경셋팅 (0) | 2022.01.10 |