Develop/JPA
[자바 ORM 표쥰 JPA 프로그래밍] 24일차 - QueryDSL(2)
자라선
2021. 11. 15. 23:03
예시로 사용된 엔티티
더보기
@Entity
public class Item {
@Id
@GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name; //이름
private int price; //가격
private int stockQuantity; //재고수량
//Getter, Setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getStockQuantity() {
return stockQuantity;
}
public void setStockQuantity(int stockQuantity) {
this.stockQuantity = stockQuantity;
}
@Override
public String toString() {
return "Item{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}
@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue
@Column(name = "ORDER_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member; //주문 회원
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
private Date orderDate; //주문시간
public void addOrderItem(OrderItem orderItem) {
orderItems.add(orderItem);
orderItem.setOrder(this);
}
//Getter, Setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Member getMember() {
return member;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", orderDate=" + orderDate +
'}';
}
@Entity
@Table(name = "ORDER_ITEM")
public class OrderItem {
@Id
@GeneratedValue
@Column(name = "ORDER_ITEM_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "ITEM_ID")
private Item item; //주문 상품
@ManyToOne
@JoinColumn(name = "ORDER_ID")
private Order order; //주문
private int orderPrice; //주문 가격
private int count; //주문 수량
//Getter, Setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public int getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(int buyPrice) {
this.orderPrice = buyPrice;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public String toString() {
return "OrderItem{" +
"id=" + id +
", buyPrice=" + orderPrice +
", count=" + count +
'}';
}
}
1. 검색조건
검색조건이 너무많아서 예시 몇개만 작성한다.
하나하나 설명하기 너무 힘들다..
JPAQuery query = new JPAQuery(em);
QItem item = QItem.item;
List<Item> list = query.from(item)
.where(item.name.eq("좋은상품").and(item.price.gt(20000))) // price > 20000
.list(item);
/**
* select
* item
* from
* Item item
* where
* item.name = ?1
* and item.price > ?2
*/
QItem item = QItem.item;
List<Item> list = query.from(item)
.where(item.price.between(10000, 20000) // between 10000 and 20000
.and(item.name.contains("상품1")) // like '%상품1%'
.and(item.name.startsWith("고급"))) // like '고급%'
.list(item);
QItem item = QItem.item;
List<Item> list = query.from(item)
.where(item.price.gt(20000))
.orderBy(item.price.desc(), item.stockQuantity.asc())
.offset(10).limit(20) // 페이징 처리
.list(item);
/**
* select
* item
* from
* Item item
* where
* item.price > ?1
* order by
* item.price desc,
* item.stockQuantity asc
*/
QOrder order = QOrder.order;
QMember member = QMember.member;
QOrderItem orderItem = QOrderItem.orderItem;
query.from(order)
.join(order.member, member) // 2번째 파라미터는 별칭을 지정
.leftJoin(order.orderItems, orderItem)
.list(order);
/**
* select
* order1
* from
*
* Order order1 inner join
* order1.member as member1
* left join
* order1.orderItems as orderItem
*/
QOrder order = QOrder.order;
QMember member = QMember.member;
QOrderItem orderItem = QOrderItem.orderItem;
query.from(order)
.leftJoin(order.orderItems, orderItem)
.on(orderItem.count.gt(2))
.list(order);
/**
* select
* order1
* from
*
* Order order1 left join
* order1.orderItems as orderItem with orderItem.count > ?1
*/
query.from(order)
.leftJoin(order.orderItems, orderItem).fetch() // 패치조인 적용
.list(order);
서브쿼리 적용
QItem item = QItem.item;
QItem itemSub = new QItem("itemSub"); // 서브쿼리용 별칭을 생성
query.from(item)
.where(item.price.eq(
new JPASubQuery().from(itemSub).unique(itemSub.price.max())
)) // 서브쿼리 적용
.list(item);
/**
* select
* item
* from
* Item item
* where
* item.price = (
* select
* max(itemSub.price)
* from
* Item itemSub
* )
*/
query.from(item)
.where(item.in(
new JPASubQuery().from(itemSub)
.where(item.name.eq(itemSub.name))
.list(itemSub)
)) // 여러 건 적용 서브쿼리 적용
.list(item);
DISTINCT
query.distinct().from(item)...
2. 프로젝션
select 절에 조회의 대상 컬럼을 지정하는 것을 의미한다.
QItem item = QItem.item;
List<String> result = query.from(item).list(item.name); // ITEM 엔티티의 NAME 필드만 조회
for(String name : result){
System.out.println("name = " + name);
}
여러 필드를 작성하면 Tuple 객체로 반환받는다.
List<Tuple> result = query.from(item).list(item.name, item.price);
// List<Tuple> result = query.from(item).list(new QTuple(item.name, item.price)); 같음
for (Tuple tuple : result) {
System.out.println("tuple = " + tuple.get(item.name));
System.out.println("tuple = " + tuple.get(item.price));
}
DTO를 작성하여 객체로 값을 받을 수 있다.
public class ItemDTO {
private String username;
private int price;
public ItemDTO() {
}
public ItemDTO(String username, int price) {
this.username = username;
this.price = price;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
QItem item = QItem.item;
List<ItemDTO> result = query.from(item)
.list(Projections.bean(ItemDTO.class, item.name.as("username"), item.price)); // ItemDTO의 필드가 username 이기 때문에 as 메소드로 별칭을 맞춰줌