상세 컨텐츠

본문 제목

[ JPA ] CriteriaBuilder

프로젝트 일기

by 성찬우 2023. 6. 1. 01:06

본문

 

JPA로 단순한 쿼리만 작성하다가 조금만 설계가 복잡해져도 "?? 어떻게..??" 하는 경우가 발생한다. 

 

그래서 JPQL의 힘을빌려 조금더 구체적인 쿼리를 작성가능하게 하는데 그래서 

 

오늘 사용해볼 것은 JPQL을 자바 코드로 작성가능하게 하는 빌더 클래스이다.

 

@PersistenceContext
private EntityManager entityManager;

우선 EntityManager를 사용하려는  class에 주입한다. 보통 서비스 로직일테니 service 클래스 일것이다. 

JPA는 JAVA객체관계형 DB 사이의 매핑을 처리하는 기술인데. EntityManager를통해서 영속성 컨텍스트, 엔티티 생명주기를 관리해준다. 즉, JAVA와 DB의 관계를 도와주는 핵심 인터페이스이다. 

또한 @PersistenceContext를 통해 JPA에서 제공하는 영속성 컨텍스트를 사용할 수 있도록한다.

 

 이제 메서드 안으로 들어가보자 

 

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ChatMessage> query = cb.createQuery(ChatMessage.class);
Root<ChatMessage> root = query.from(ChatMessage.class);

이게 기본적인 형태이다. 

 

Builder();를 통해 Query를 작성하는데 타입은 내가 만들어 내려는 엔티티.class가 들어가면 된다. 

이제 조회를 시작한다는 의미로 Root 객체를 생성한다. 

이후 root 변수에 하나하나 값을 넣어주면 되는데 

Expression<Long> index = root.get("index").as(Long.class);

이렇게 root에서 index 라는 값을 넣고 이는 Long으로 지정하여 매핑을 가능하도록 한다. 이렇게 해주는 이유는 나중에 API를 통해서 들어온 JSON 값을 비교하여 넣어줘야하기 때문에 타입이 다르면 에러가 발생한다. 

Expression<String> conSender = root.get("sender").as(String.class);

이는 String 타입으로 변환하는 예시이다. 

ENUM타입은 알아서 매핑하니 굳이 .as를 해줄 필요없다. 

 

Predicate condition1 = cb.and(
        cb.equal(index , API로 받은값1),
        cb.equal(conRecipient, API로 받은값1)
);

Predicate condition2 = cb.and(
        cb.equal(index , API로 받은값2),
        cb.equal(conRecipient, API로 받은값2
);

이렇게 Predicate 객체를 생성해준다. 여러개 만들어줘도 된다. 

이렇게 만들어준 Predicate 객체를 하나로 만들어주기 위해서는 

 

Predicate finalCondition = cb.or(condition1, condition2);

이렇게 하나로 합쳐줄수 있다. 

 

이후 

 

query.select(root).where(finalCondition);

root에 finalCondition 을 넣어줘서 쿼리 넣고

query.orderBy(cb.asc(root.get("createdAt")));

내가 생성한 timeTable값으로 정렬시켜달라 했다. 

 

TypedQuery<ChatMessage> typedQuery = entityManager.createQuery(query);

 

최종적으로 entityManager에서 createQuery를 해서 typedQuery에 받아와서 

typedQuery.getResultList()

하면 값을 전달 받을 수 있다. 

 

 

 

필자의 경우 A, B유저 채팅을 가져오는데 

A가 발신자 , B가 수신자의 경우의 rows들과 

A가 수신자, B가 발신자의 경우의 rows들을 모두 불러오기 위해서 활용하게 되었다. 

'프로젝트 일기' 카테고리의 다른 글

[JPQL] 기초  (1) 2023.06.09
[DOCKER] 배포  (0) 2023.06.06
P들의 여행 스타트  (0) 2023.05.09

관련글 더보기

댓글 영역