Search
Duplicate
📒

[Spring DB] xx. JPA 사용, 예외 변환

상태
미진행
수업
Database Study
주제
JPA
4 more properties
참고

JPA 설정

NOTE
build.gradle
// JDBC를 주석처리하고 JPA, 스프링 데이터 JPA 추가 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //implementation 'org.springframework.boot:spring-boot-starter-jdbc'
Java
복사
JPA에 JDBC가 포함되어있어서 주석처리 해줌
application.properties
//하이버네이트가 생성하고 실행하는 SQL을 확인할 수 있다. logging.level.org.hibernate.SQL=DEBUG //SQL에 바인딩 되는 파라미터를 확인할 수 있다. logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Java
복사

JPA 적용

NOTE
JPA에서 가장 중요한 부분은 객체와 테이블을 맵핑하는 것이다.

JPA - DTO

NOTE
@Data @Entity public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "item_name", length = 10) // 생략가능 private String itemName; private Integer price; private Integer quantity; public Item() {} public Item(String itemName, Integer price, Integer quantity) { this.itemName = itemName; this.price = price; this.quantity = quantity; } }
Java
복사
@Entity : JPA가 사용하는 객체라는 의미. 해당 어노테이션이 있어야 JPA가 인식할 수 있다
@ID : 테이블의 PK와 해당 필드를 맵핑한다
@Column : 객체의 필드를 테이블의 컬럼과 매핑한다
itemNameitem_name 자동 변환해줌, 생략가능
JPApulbic 또는 protected의 기본 생성자가 필수이다!

JPA - Repository

NOTE
@Slf4j @Repository @Transactional public class JpaItemRepositoryV1 implements ItemRepository { private final EntityManager em; public JpaItemRepositoryV1(EntityManager em) { this.em = em; } //... }
Java
복사
스프링을 통해 엔티티 매니저(EntityManager)라는 것을 주입받은 것을 확인할 수 있다
JPA의 모든 동작은 EntityManager를 통해서 이루어진다.
EntityManager는 내부에 dataSource를 가지고 있고, 데이터베이스에 접근할 수 있다.
@Transactional
JPA의 모든 데이터 변경(등록, 수정, 삭제)는 필수적으로 트랜잭션 안에서 처리된다.
따라서 리포지토리에 트랜잭션을 걸어줌

save() - 저장

@Override public Item save(Item item) { em.persist(item); return item; }
Java
복사
JPA에서 객체를 테이블에 저장할 때는, EntityManager가 제공하는 em.persist() 사용

update() - 수정

@Override public void update(Long itemId, ItemUpdateDto updateParam) { Item findItem = em.find(Item.class, itemId); findItem.setItemName(updateParam.getItemName()); findItem.setPrice(updateParam.getPrice()); findItem.setQuantity(updateParam.getQuantity()); }
Java
복사
PK를 기준으로 entity를 조회할 때는 find()를 사용한다.
그런데 em.update()같은 메서드가 전혀 호출되지 않았다???
JPA트랜잭션이 commit되는 시점에, 변경된 entity객체가 있는지 확인한다
특정 entity가 변경된 경우 UPDATE SQL을 실행한다.

findById() - 단건 조회, JPQL

@Override public List<Item> findAll(ItemSearchCond cond) { String jpql = "select i from Item i"; //동적 쿼리 생략 TypedQuery<Item> query = em.createQuery(jpql, Item.class); return query.getResultList(); }
Java
복사
JPAJPQL(JAva Persistence Query Language)라는 객체지향 쿼리 언어를 제공한다.
주로 여러 데이터를 복잡한 조건으로 조회할 때 사용
SQL은 테이블 대상 → JPAQL은 entity객체를 대상으로 SQL을 실행한다.
객체를 대상으로 하기 때문에 from다음에 Item entity객체 이름이 들어간다.
select i from Item i where i.itemName like concat('%',:itemName,'%') and i.price <= :maxPrice
SQL
복사
실행된 JPQL
select item0_.id as id1_0_, item0_.item_name as item_nam2_0_, item0_.price as price3_0_, item0_.quantity as quantity4_0_ from item item0_ where (item0_.item_name like ('%'||?||'%')) and item0_.price<=?
SQL
복사
JPQL을 통해 실행된 SQL

JPA 예외 변환

NOTE
EntityManager는 순수한 JPA 기술이고, 스프링과 관계없는 JPA 예외가 발생한다.
JPAPersistenceException과 그 하위 예외를 발생시킨다.
JPA예외를 스프링 예외 추상화로 추상화시키기 위해선 @Repository가 필요하다.

@Repository의 기능

NOTE
예외 변환 전
@Repository를 적용하지 않으면 JPA예외가 그대로 던져진다.
예외 변환 후
@Repository를 통해 AOP 프록시는 JPA관련 예외가 발생하면 예외 변환기를 통해 발생한 예외를 스프링 데이터 접근 예외로 변경시켜준다.