카테고리 없음

spring boot querydsl study (2)

머룽 2023. 4. 20. 09:53
우리는 어제 querydsl의 기본적인 API들을 살펴보고 변경사항도 같이 살펴봤다. 이번시간은 간단한 동적쿼리와 join에 대해 알아보자. 심도있는 것은 나중에 살펴보도록하고.. 일단 엔티티부터 코드로 보자. 아래 엔티티로 공부를 할 예정이라 포스팅도 같이 했다. 추가되면 그때 그때 추가 하겠다.
@Entity
public class Account {

  @Id
  @GeneratedValue
  @Column(name = "ACCOUNT_ID")
  private Long id;

  private String name;

  private String password;

  private String email;

  @OneToMany(mappedBy = "account")
  private List<Order> orders = new ArrayList<>();

  //getter setter hashcode equals etc..
}

@Entity
@Table(name = "ORDERS")
public class Order {

  @Id
  @GeneratedValue
  @Column(name = "ORDER_ID")
  private Long id;

  @ManyToOne
  @JoinColumn(name = "ACCOUNT_ID")
  private Account account;

  @OneToMany(mappedBy = "order")
  private List<OrderItem> orderItems = new ArrayList<>();

  @Temporal(TemporalType.TIMESTAMP)
  private Date orderDate;

  //getter setter hashcode equals etc..
}

@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 Integer orderPrice;

  private Integer count;

  //getter setter hashcode equals etc..
}

@Entity
public class Item {

  @Id
  @GeneratedValue
  @Column(name = "ITEM_ID")
  private Long id;

  private String name;

  private Integer price;

  private Integer stockQuantity;

  //getter setter hashcode equals etc..
}
데이터들은 각자 원하는 대로 넣어 보자. Order라는 레파지토리를 만들어서 아래와 같이 하자.
@Override
public List<Order> orders(){
  QOrder order = QOrder.order;
  QAccount account = QAccount.account;
  return from(order)
    .leftJoin(order.account, account).fetchJoin()
    .fetch();
}
이것은 order와 account 엔티티를 leftjoin 한것이다. fetchJoin을 쓴 이유는 한방쿼리를 위해.. N+1을 막을라고 한 것이다. 이 예제에선 그닥 필요 없을지도 모르지만 그냥 넣어 뒀다. 일반 sql문과 비슷하다. from부터 시작해서 leftjoin, innerjoin, rightJoin 기타 등등이 있다. leftjoin 조인을 했지만 innerjoin, rightJoin등 문법 자체는 비슷비슷하다. 다음시간엔 좀 더 구체적으로 알아보겠다. 이번에는 동적쿼리이다. 동적쿼리라 해서 뭐 대단한 것도 없다.
@Override
public List<Order> orders(Long id){
  QOrder order = QOrder.order;
  QAccount account = QAccount.account;
  JPQLQuery query = from(order)
    .leftJoin(order.account, account);

  if(id != null){
    query.where(account.id.goe(id));
  }
  return query
    .fetchJoin().fetch();
}
약간 예제가 좀 그렇지만 id가 null이 아닐때 id보다 accountid 크거나 같은 것을 조회하는 동적쿼리이다. 예제가 썩 맘에 들진 않지만 그래도 이렇게 하는 것이다 이해정도만 하면 될 듯싶다. goe는 크거나 같음을 의미한다. 이외에도 lt, gt, loe, eq, ne, like, between, max, min 등등 여러가지가 존재한다. 이것은 너무 많으므로 생략.. 나중에 그냥 한번씩 살펴보는 정도면 될 듯싶다. 위와 같이 하는 것 말고도 다른 방법이 존재 한다. BooleanBuilder를 써도 가능하다.
@Override
public List<Order> orders(Long id){
  QOrder order = QOrder.order;
  QAccount account = QAccount.account;
  JPQLQuery query = from(order)
    .leftJoin(order.account, account).fetchJoin();

  BooleanBuilder booleanBuilder = new BooleanBuilder();

  if(id != null){
    booleanBuilder.and(account.id.goe(id));
  }
  query.where(booleanBuilder);
  return query.fetch();
}
위와 같이 BooleanBuilder를 써써 동적 쿼리를 가능하게 할 수 있다. 이번시간에는 join과 동적쿼리에 대해서 알아봤다. 간단하게 알아봤지만 다음시간에는 조금더 심도있게 알아볼 예정이다. 아니면 서브쿼리를 먼저 할까.. 아무튼 필자가 먼저 하고 싶은거를 선택해서 다음에 진행 하겠다. 엔티티는 이번시간에 했던 엔티티를 계속적으로 할 듯 싶다.