JPA 예시

wangjh789·2022년 8월 18일
0

[Spring] 스프링-DB-2

목록 보기
5/21

JPA는 public 또는 protected의 기본 생성자가 필수이다.
(JPA가 프록시 기술을 사용하기 위해)

@Repository
@RequiredArgsConstructor
public class JpaItemRepository implements ItemRepository {

    private final EntityManager em;

    @Override
    @Transactional
    public Item save(Item item) {
        em.persist(item);
        return item;
    }

    @Override
    @Transactional
    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());
    }

    @Override
    public Optional<Item> findById(Long id) {
        Item item = em.find(Item.class, id);
        return Optional.ofNullable(item);
    }

    @Override
    public List<Item> findAll(ItemSearchCond cond) {
        String jpql = "select i from Item i";

        Integer maxPrice = cond.getMaxPrice();
        String itemName = cond.getItemName();
        if (StringUtils.hasText(itemName) || maxPrice != null) {
            jpql += " where";
        }
        boolean andFlag = false;
        List<Object> param = new ArrayList<>();
        if (StringUtils.hasText(itemName)) {
            jpql += " i.itemName like concat('%',:itemName,'%')";
            param.add(itemName);
            andFlag = true;
        }
        if (maxPrice != null) {
            if (andFlag) {
                jpql += " and";
            }
            jpql += " i.price <= :maxPrice";
            param.add(maxPrice);
        }
        log.info("jpql={}", jpql);
        TypedQuery<Item> query = em.createQuery(jpql, Item.class);
        if (StringUtils.hasText(itemName)) {
            query.setParameter("itemName", itemName);
        }
        if (maxPrice != null) {
            query.setParameter("maxPrice", maxPrice);
        }
        return query.getResultList();
    }
}

JPA를 설정하려면 EntityManagerFacotry, Jpa 트랜잭션 매니저 등 다양한 설정을 해야하지만 스프링 부트는 이 과정을 모두 자동화 해준다.

JPA에서 데이터를 변경할 떄는 @Transactional이 필수이다.일반적으로 서비스 계층에 트랜잭션을 건다.
(최소한 데이터를 변경하는 메서드에 꼭 붙여야 한다.)

Create
em.persist(item);
위 처럼 간단하게 객체를 DB에 임시데이터를 넣어준 후 item 인스턴스에 id값을 채워준다.

Update
따로 persist() 함수를 실행하지 않아도 트랜잭션이 커밋되는 시점에 더티체킹을 통해 변경사항을 찾고 이에 맞게 쿼리를 날려준다.
(조회한 시점에 스냅샷을 만들어 보관해둔다.)

READ
동적쿼리와 같은 복잡한 쿼리의 경우 JPQL을 직접 짜서 수행해야한다. (대소문자 구분)

동적쿼리 는 QueryDsl을 사용하도록 하자

profile
기록

0개의 댓글