네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

JPA 특징 중에 하나인 Criteria Queries

- raw SQL문 없이 객체 지향적으로 쿼리를 작성할 수 있다.

1. Maven Dependencies

pom.xml 파일에 Hibernate 관련 의존성을 추가해준다.

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>   
    <version>5.3.2.Final</version>
</dependency>

참고로 spring-booy-starter-data-jpa에는 hibernate관련 의존성이 들어있다. spring data jpa를 사용하는 경우 hibernate 관련 의존성을 추가하지 않아도 된다.
또, spring boot에서 의존성을 추가할 때는 버전을 입력하지 않아도 spring boot에서 자동으로 버전 관리를 해준다.

spring-boot-starter-data-jpa에 hibernate 관련 의존성이 있다.

2. 예제

Item.java

@Getter
@Setter
public class Item implements Serializable {
    
    private Integer itemId;
    private String itemName;
    private String itemDescription;
    private Integer itemPrice;
}


데이터베이스에서 Item의 모든 row를 가져오는 간단한 criteria query를 작성해보자.

Session session = HibernateUtil.getHibernateSession();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Item> cr = cb.createQuery(Item.class);
Root<Item> root = cr.from(Item.class);
cr.select(root);

Query<Item> query = session.createQuery(cr);
List<Item> results = query.getResultList();


[where() 메서드를 사용하여 구체적인 조건을 작성]
1. 가격이 1000 초과인 Item을 가져오기

cr.select(root).where(cb.gt(root.get("itemPrice"), 1000)); // 가격이 1000 초과인 Item
cr.select(root).where(cb.lt(root.get("itemPrice"), 1000)); // 가격이 1000 미만인 Item
cr.select(root).where(cb.like(root.get("itemName"), "%chair%")); // 이름에 chair를 포함하는 Item
cr.select(root).where(cb.between(root.get("itemPrice"), 100, 200)); // 가격이 100과 200 사이인 Item
cr.select(root).where(root.get("itemName").in("Skate Board", "Paint", "Glue")); // 이름이 Skate Board 거나 Paint 거나 Glue인 Item
cr.select(root).where(cb.isNull(root.get("itemDescription"))); // 설명이

2. 가격이 1000 미만인 Item 가져오기

cr.select(root).where(cb.lt(root.get("itemPrice"), 1000));

3. 가격이 100과 200 사이인 Item 가져오기

cr.select(root).where(cb.between(root.get("itemPrice"), 100, 200));

4. 이름이 Skate Board, Paint, Glue인 Item 가져오기

cr.select(root).where(root.get("itemName").in("Skate Board", "Paint", "Glue"));

5. 두개 이상의 조건이 있을 땐 Predicate를 사용한다.

Predicate[] predicates = new Predicate[2];
predicates[0] = cb.isNull(root.get("itemDescription"));
predicates[1] = cb.like(root.get("itemName"), "%chair%");
cr.select(root).where(predicates);
Predicate greaterThanPrice = cb.gt(root.get("itemPrice"), 1000));
Predicate chairItems = cb.like(root.get("itemName"), "%chair%");

cr.select(root).where(cb.or(greaterThanPrice, chairItems));
cr.select(root).where(cb.and(greaterThanPrice, chairItems));

[orderBy(), asc(), desc() 메서드로 sorting]

cr.orderBy(cb.asc(root.get("itemName")), cb.desc(root.get("itemPrice")));

[projections, aggregates, grouping function]

CriteriaQuery<Long> cr = cb.createQuery(Long.class);
Root<Item> root = cr.from(Item.class);
cr.select(cb.count(root));
Query<Long> query = session.createQuery(cr);
List<Long> itemProjected = query.getResultList();


CriteriaUpdate(JPA 2.1부터)

CriteriaUpdate<Item> criteriaUpdate = cb.createCriteriaUpdate(Item.class);
Root<Item> root = criteriaUpdate.from(Item.class);
criteriaUpdate.set("itemPrice", newPrice);
criteriaUpdate.where(cb.equal(root.get("itemPrice"), oldPrice));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaUpdate).executeUpdate();
transactionl.commit();

set() 메서드를 사용해서 새로운 값을 넣어준다.

CriteriaDelete

CriteriaDelete<Item> criteriaDelete = cb.createCriteriaDelete(Item.class);
Root<Item> root = criteriaDelete.from(Item.class);
criteriaDelete.where(cb.greaterThan(root.get("itemPrice"), targetPrice));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaDeleter).executeUpdate();
transaction.commit();








728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !