+ All Categories
Home > Documents > QueryDSL - Tistory

QueryDSL - Tistory

Date post: 20-Oct-2021
Category:
Upload: others
View: 5 times
Download: 0 times
Share this document with a friend
121
QueryDSL type-safe Query 발표자 : 김영한 1
Transcript
Page 1: QueryDSL - Tistory

QueryDSLtype-safe����������� ������������������  Query

발표자����������� ������������������  :����������� ������������������  김영한

1

Page 2: QueryDSL - Tistory

목차

•문제

•JPA����������� ������������������  Query

•QueryDSL?

•QueryDSL-JPA

•기능����������� ������������������  살펴보기

•Spring����������� ������������������  Data����������� ������������������  JPA����������� ������������������  +����������� ������������������  Querydsl

2

Page 3: QueryDSL - Tistory

문제

3

Page 4: QueryDSL - Tistory

긴급����������� ������������������  요구사항

•검색조건����������� ������������������  추가

•나이

•이름

•퇴근시간����������� ������������������  10분전...

4

Page 5: QueryDSL - Tistory

기능����������� ������������������  추가

이정도는 발로 만들어 주지

5

Page 6: QueryDSL - Tistory

쿼리����������� ������������������  추가

String����������� ������������������  sql����������� ������������������  =

“select����������� ������������������  *����������� ������������������  from����������� ������������������  member”����������� ������������������  +

“where����������� ������������������  name����������� ������������������  like����������� ������������������  ?”����������� ������������������  +

“and����������� ������������������  age����������� ������������������  between����������� ������������������  ?����������� ������������������  and����������� ������������������  ?”

6

Page 7: QueryDSL - Tistory

컴파일����������� ������������������  완료

7

Page 8: QueryDSL - Tistory

배포����������� ������������������  완료

8

Page 9: QueryDSL - Tistory

퇴근����������� ������������������  완료

9

Page 10: QueryDSL - Tistory

버그����������� ������������������  발생

10

Page 11: QueryDSL - Tistory

리콜����������� ������������������  완료??

그럴리가����������� ������������������  없어분명����������� ������������������  빌드는����������� ������������������  성공했어!

11

Page 12: QueryDSL - Tistory

버그String����������� ������������������  sql����������� ������������������  =

“select����������� ������������������  *����������� ������������������  from����������� ������������������  member”����������� ������������������  +

“where����������� ������������������  name����������� ������������������  like����������� ������������������  ?”����������� ������������������  +

“and����������� ������������������  age����������� ������������������  between����������� ������������������  ?����������� ������������������  and����������� ������������������  ?”

[합치면]

“select����������� ������������������  *����������� ������������������  from����������� ������������������  memberwhere����������� ������������������  name����������� ������������������  like����������� ������������������  ?and����������� ������������������  age����������� ������������������  between����������� ������������������  ?����������� ������������������  and����������� ������������������  ?”

12

Page 13: QueryDSL - Tistory

QUERY의����������� ������������������  문제점

•QUERY는����������� ������������������  문자,����������� ������������������  Type-check����������� ������������������  불가능

•실행해����������� ������������������  보기����������� ������������������  전까지����������� ������������������  작동여부����������� ������������������  확인����������� ������������������  불가

13

Page 14: QueryDSL - Tistory

에러는����������� ������������������  크게����������� ������������������  2가지

•컴파일����������� ������������������  에러����������� ������������������  (좋은����������� ������������������  에러)

•런타임����������� ������������������  에러����������� ������������������  (나쁜����������� ������������������  에러)

14

Page 15: QueryDSL - Tistory

도메인����������� ������������������  고수?

전����������� ������������������  SQL을����������� ������������������  빨리����������� ������������������  작성하기����������� ������������������  위해����������� ������������������  컬럼명����������� ������������������  정도는����������� ������������������  모두����������� ������������������  

외운답니다.

SELECT����������� ������������������  NAME,����������� ������������������  AGE����������� ������������������  ..

15

Page 16: QueryDSL - Tistory

SQL...

•만약����������� ������������������  SQL이����������� ������������������  Class처럼����������� ������������������  Type이����������� ������������������  있고����������� ������������������  Java코드로����������� ������������������  작성����������� ������������������  할����������� ������������������  수����������� ������������������  있다면?

•type-safe

16

Page 17: QueryDSL - Tistory

Type-safe

•컴파일시����������� ������������������  에러����������� ������������������  체크����������� ������������������  가능

•Code-assistant����������� ������������������  x����������� ������������������  100!!!

•CTRL����������� ������������������  +����������� ������������������  SPACE����������� ������������������  +����������� ������������������  .����������� ������������������  (DOT)

17

Page 18: QueryDSL - Tistory

QueryDSL-SQL

•SQL을����������� ������������������  Java����������� ������������������  로����������� ������������������  type-safe하게����������� ������������������  개발����������� ������������������  할����������� ������������������  수����������� ������������������  있는����������� ������������������  프레임워크

18

Page 19: QueryDSL - Tistory

QueryDSL-SQL

19

Page 20: QueryDSL - Tistory

QueryDSL

•하지만����������� ������������������  지금은����������� ������������������  ORM시대????

20

Page 21: QueryDSL - Tistory

JPA����������� ������������������  Queryjava����������� ������������������  ORM

21

Page 22: QueryDSL - Tistory

질문����������� ������������������  :����������� ������������������  사람을����������� ������������������  찾아보자

•20~40살

•성����������� ������������������  =����������� ������������������  김씨

•나이����������� ������������������  많은����������� ������������������  순서

•3명을����������� ������������������  출력하라.

22

Page 23: QueryDSL - Tistory

회원@Entitypublic����������� ������������������  class����������� ������������������  Member����������� ������������������  {

����������� ������������������   @Id����������� ������������������  @GeneratedValue����������� ������������������   private����������� ������������������  Long����������� ������������������  id;����������� ������������������   private����������� ������������������  String����������� ������������������  name;����������� ������������������   private����������� ������������������  int����������� ������������������  age;...}

23

Page 24: QueryDSL - Tistory

회원����������� ������������������  Table

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  create����������� ������������������  table����������� ������������������  Member����������� ������������������  (����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  id����������� ������������������  bigint����������� ������������������  auto����������� ������������������  primary����������� ������������������  key,����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  age����������� ������������������  integer����������� ������������������  not����������� ������������������  null,����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  name����������� ������������������  varchar(255)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  )

24

Page 25: QueryDSL - Tistory

JPA����������� ������������������  에서����������� ������������������  QUERY����������� ������������������  방법은크게����������� ������������������  3가지

•1.����������� ������������������  JPQL(HQL)

•2.����������� ������������������  Criteria����������� ������������������  API

•3.����������� ������������������  MetaModel����������� ������������������  Criteria����������� ������������������  API(type-safe)

25

Page 26: QueryDSL - Tistory

1.����������� ������������������  JPQL(HQL)����������� ������������������   @Test����������� ������������������   public����������� ������������������  void����������� ������������������  jpaJpqlQuery()����������� ������������������  {����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   String����������� ������������������  query����������� ������������������  =����������� ������������������  ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   "select����������� ������������������  m����������� ������������������  from����������� ������������������  Member����������� ������������������  m����������� ������������������  "����������� ������������������  +����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   "where����������� ������������������  m.age����������� ������������������  between����������� ������������������  20����������� ������������������  and����������� ������������������  40����������� ������������������  "����������� ������������������  +����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   "����������� ������������������  ����������� ������������������  ����������� ������������������  and����������� ������������������  m.name����������� ������������������  like����������� ������������������  '김%'����������� ������������������  "����������� ������������������  +����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   "order����������� ������������������  by����������� ������������������  m.age����������� ������������������  desc";����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  resultList����������� ������������������  =����������� ������������������  ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   entityManager.createQuery(query,����������� ������������������  Member.class)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .setMaxResults(3).getResultList();����������� ������������������   ����������� ������������������  ����������� ������������������   }

26

Page 27: QueryDSL - Tistory

1.����������� ������������������  JPQL(HQL)

•장점����������� ������������������  :����������� ������������������  SQL����������� ������������������  QUERY와����������� ������������������  비슷해서����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  금방����������� ������������������  익숙해짐

•단점����������� ������������������  :����������� ������������������  type-safe����������� ������������������  아님����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  동적쿼리����������� ������������������  생성이����������� ������������������  어려움

27

Page 28: QueryDSL - Tistory

2.����������� ������������������  Criteria����������� ������������������  API����������� ������������������   @Test����������� ������������������   public����������� ������������������  void����������� ������������������  jpaCriteriaQuery()����������� ������������������  {����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   CriteriaBuilder����������� ������������������  cb����������� ������������������  =����������� ������������������  entityManager.getCriteriaBuilder();����������� ������������������   ����������� ������������������   CriteriaQuery<Member>����������� ������������������  cq����������� ������������������  =����������� ������������������  cb.createQuery(Member.class);����������� ������������������   ����������� ������������������   Root<Member>����������� ������������������  root����������� ������������������  =����������� ������������������  cq.from(Member.class);����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   Path<Integer>����������� ������������������  age����������� ������������������  =����������� ������������������  root.get("age");����������� ������������������   ����������� ������������������   Predicate����������� ������������������  between����������� ������������������  =����������� ������������������  cb.between(age,����������� ������������������  20,40);

����������� ������������������   ����������� ������������������   Path<String>����������� ������������������  path����������� ������������������  =����������� ������������������  root.get("name");����������� ������������������   ����������� ������������������   Predicate����������� ������������������  like����������� ������������������  =����������� ������������������  cb.like(path,����������� ������������������  "김%");����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   CriteriaQuery<Member>����������� ������������������  query����������� ������������������  =����������� ������������������  cq.where(����������� ������������������  cb.and(between,����������� ������������������  like)����������� ������������������  );����������� ������������������   ����������� ������������������   query.orderBy(cb.desc(age));����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  resultList����������� ������������������  =����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  entityManager.createQuery(query).setMaxResults(3).getResultList();

����������� ������������������   }

28

Page 29: QueryDSL - Tistory

2.����������� ������������������  Criteria����������� ������������������  API

29

Page 30: QueryDSL - Tistory

2.����������� ������������������  Criteria����������� ������������������  API

����������� ������������������  select����������� ������������������  id,����������� ������������������  age,����������� ������������������  name����������� ������������������  from����������� ������������������  MEMBER����������� ������������������  ����������� ������������������  where����������� ������������������  age����������� ������������������  between����������� ������������������  20����������� ������������������  and����������� ������������������  40����������� ������������������  and����������� ������������������  name����������� ������������������  like����������� ������������������  '김%'����������� ������������������  order����������� ������������������  by����������� ������������������  age����������� ������������������  desc����������� ������������������  limit����������� ������������������  3

30

Page 31: QueryDSL - Tistory

2.����������� ������������������  Criteria����������� ������������������  API

•장점����������� ������������������  :����������� ������������������  동적쿼리����������� ������������������  생성이����������� ������������������  쉬움??

•단점

•1.����������� ������������������  type-safe����������� ������������������  아님

•2.����������� ������������������  복잡함

•3.����������� ������������������  알아야����������� ������������������  할게����������� ������������������  너무����������� ������������������  많음

•4.����������� ������������������  과거����������� ������������������  EJB공부����������� ������������������  할����������� ������������������  때가����������� ������������������  생각남...

31

Page 32: QueryDSL - Tistory

3.����������� ������������������  MetaModel����������� ������������������  Criteria����������� ������������������  API(type-safe)

•root.get("age")����������� ������������������  ->����������� ������������������  root.get(Member_.age)

•Criteria����������� ������������������  API����������� ������������������  +����������� ������������������  MetaModel

•Criteria����������� ������������������  API와����������� ������������������  거의����������� ������������������  동일

•type-safe

•복잡하긴����������� ������������������  마찬가지

32

Page 33: QueryDSL - Tistory

이건����������� ������������������  아니야--;timowest

33

Page 34: QueryDSL - Tistory

QueryDSL

34

Page 35: QueryDSL - Tistory

QueryDSL����������� ������������������  분석

•Query����������� ������������������  :����������� ������������������  문의,����������� ������������������  조회,����������� ������������������  질문,����������� ������������������  ?

•Query����������� ������������������  !=����������� ������������������  SQL

35

Page 36: QueryDSL - Tistory

QueryDSL����������� ������������������  분석

•Domain(도메인)

•Specific(특화)

•Language(언어)

36

Page 37: QueryDSL - Tistory

DSL

•도메인����������� ������������������  +����������� ������������������  특화����������� ������������������  +����������� ������������������  언어

•특정한����������� ������������������  도메인에����������� ������������������  초점을����������� ������������������  맞춘����������� ������������������  제한적인����������� ������������������  표현력을����������� ������������������  가진����������� ������������������  컴퓨터����������� ������������������  프로그래밍����������� ������������������  언어

•특징����������� ������������������  :����������� ������������������  단순,����������� ������������������  간결,����������� ������������������  유창

37

Page 38: QueryDSL - Tistory

QueryDSL

•조회����������� ������������������  +����������� ������������������  도메인����������� ������������������  +����������� ������������������  특화����������� ������������������  +����������� ������������������  언어

•조회에����������� ������������������  특화된����������� ������������������  프로그래밍����������� ������������������  언어

38

Page 39: QueryDSL - Tistory

[Persistence]JPA,����������� ������������������  JDO,����������� ������������������  SQL,����������� ������������������  JAVA����������� ������������������  Collections,����������� ������������������  RDF,����������� ������������������  Lucene,����������� ������������������  Hibernate����������� ������������������  Search,����������� ������������������  

Mongo����������� ������������������  Db

QueryDSL����������� ������������������  API

데이터����������� ������������������  조회����������� ������������������  기능����������� ������������������  추상화

39

Page 40: QueryDSL - Tistory

QueryDSL?

•type-safe

•조회에����������� ������������������  특화된����������� ������������������  프로그래밍����������� ������������������  언어

•단순,����������� ������������������  간결,����������� ������������������  유창

•다양한����������� ������������������  저장소����������� ������������������  조회����������� ������������������  기능����������� ������������������  통합

40

Page 41: QueryDSL - Tistory

QueryDSL?

•JPA,����������� ������������������  JDO,����������� ������������������  SQL����������� ������������������  같은����������� ������������������  Backends를����������� ������������������  위해����������� ������������������  type-safe����������� ������������������  SQL을����������� ������������������  만드는����������� ������������������  프레임워크

41

Page 42: QueryDSL - Tistory

Type-safeQuery����������� ������������������  Type����������� ������������������  생성

Member javaMember table

Member ...

QMEMBER.java

코드생성기

생성

42

Page 43: QueryDSL - Tistory

코드생성기

•APT����������� ������������������  :����������� ������������������  Annotation����������� ������������������  Processing����������� ������������������  Tool

•@Deprecated

•@Override

•@SuppressWarning

•@Entity

•Table����������� ������������������  Meta����������� ������������������  :����������� ������������������  Querydsl-maven-plugin

43

Page 44: QueryDSL - Tistory

QueryDSL-JPA

44

Page 45: QueryDSL - Tistory

Querydsl-JPA

•Querydsl은����������� ������������������  JPQL(HQL)을����������� ������������������  typesafe����������� ������������������  하게����������� ������������������  작성하기����������� ������������������  위해����������� ������������������  만들어짐

•너를����������� ������������������  위해����������� ������������������  만들었다!

45

Page 46: QueryDSL - Tistory

질문����������� ������������������  :����������� ������������������  사람을����������� ������������������  찾아보자

•20~40살

•성����������� ������������������  =����������� ������������������  김씨

•나이����������� ������������������  많은����������� ������������������  순서

•3명을����������� ������������������  출력하라.

46

Page 47: QueryDSL - Tistory

회원����������� ������������������  Table

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  create����������� ������������������  table����������� ������������������  Member����������� ������������������  (����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  id����������� ������������������  bigint����������� ������������������  auto����������� ������������������  primary����������� ������������������  key,����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  age����������� ������������������  integer����������� ������������������  not����������� ������������������  null,����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  name����������� ������������������  varchar(255)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  )

47

Page 48: QueryDSL - Tistory

회원@Entitypublic����������� ������������������  class����������� ������������������  Member����������� ������������������  {

����������� ������������������   @Id����������� ������������������  @GeneratedValue����������� ������������������   private����������� ������������������  Long����������� ������������������  id;����������� ������������������   private����������� ������������������  String����������� ������������������  name;����������� ������������������   private����������� ������������������  int����������� ������������������  age;...}

48

Page 49: QueryDSL - Tistory

QueryDSL-JPA

Member.java@Entity

QMember.java

APT

생성

49

Page 50: QueryDSL - Tistory

@Generated("com.mysema.query.codegen.EntitySerializer")

public����������� ������������������  class����������� ������������������  QMember����������� ������������������  extends����������� ������������������  EntityPathBase<Member>����������� ������������������  {

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  NumberPath<Long>����������� ������������������  id����������� ������������������  =����������� ������������������  createNumber("id",����������� ������������������  Long.class);����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  NumberPath<Integer>����������� ������������������  age����������� ������������������  =����������� ������������������  createNumber("age",����������� ������������������  Integer.class);����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  StringPath����������� ������������������  name����������� ������������������  =����������� ������������������  createString("name");

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  static����������� ������������������  final����������� ������������������  QMember����������� ������������������  member����������� ������������������  =����������� ������������������  new����������� ������������������  QMember("member");

...}

자동생성된����������� ������������������  회원Query

50

Page 51: QueryDSL - Tistory

QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member

query.from(m).where(����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  m.age.between(20,40),����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  m.name.like("김%")).orderBy(m.age.desc()).limit(3).list(m);

Querydsl-JPA

51

Page 52: QueryDSL - Tistory

����������� ������������������   ����������� ������������������   JPAQuery����������� ������������������  query����������� ������������������  =����������� ������������������  new����������� ������������������  JPAQuery����������� ������������������  (entityManager);����������� ������������������  ����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  query.from(m).where(����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   m.age.between(20,����������� ������������������  40).and(m.name.like("김%"))����������� ������������������   ����������� ������������������   )����������� ������������������   ����������� ������������������   .orderBy(m.age.desc()).limit(3)����������� ������������������   ����������� ������������������   .list(m);

Querydsl-JPA

52

Page 53: QueryDSL - Tistory

생성된����������� ������������������  쿼리

����������� ������������������  select����������� ������������������  id,����������� ������������������  age,����������� ������������������  name����������� ������������������  from����������� ������������������  MEMBER����������� ������������������  where����������� ������������������  age����������� ������������������  between����������� ������������������  20����������� ������������������  and����������� ������������������  40����������� ������������������  ����������� ������������������  and����������� ������������������  name����������� ������������������  like����������� ������������������  '김%'����������� ������������������  order����������� ������������������  by����������� ������������������  age����������� ������������������  desc����������� ������������������  limit����������� ������������������  3

53

Page 54: QueryDSL - Tistory

작동����������� ������������������  방식

SQLJPQLQUERYDSL

생성 생성

54

Page 55: QueryDSL - Tistory

Querydsl-JPA•장점

•type-safe

•단순함

•쉬움

•EJB->Spring����������� ������������������  정도의����������� ������������������  차이?

•단점

•APT를����������� ������������������  설정해야함

55

Page 56: QueryDSL - Tistory

기능����������� ������������������  살펴보기QueryDSL-JPA

56

Page 57: QueryDSL - Tistory

구성Query

ex)����������� ������������������  from,����������� ������������������  where,����������� ������������������  join

Path

ex)����������� ������������������  QMember,����������� ������������������  QMember.name

Expression

ex)����������� ������������������  name.eq,����������� ������������������  name.gt

57

Page 58: QueryDSL - Tistory

기능����������� ������������������  살펴보기

•from

•innerJoin,����������� ������������������  join,����������� ������������������  leftJoin,����������� ������������������  fullJoin,����������� ������������������  on

•where����������� ������������������  (and,����������� ������������������  or,����������� ������������������  allOf,����������� ������������������  anyOf)

•groupBy

•having

•orderBy����������� ������������������  (desc,����������� ������������������  asc)

•limit,����������� ������������������  offset,����������� ������������������  restrict(limit����������� ������������������  +����������� ������������������  offset)����������� ������������������  (Paging)

58

Page 59: QueryDSL - Tistory

기능����������� ������������������  살펴보기

•list

•listResults����������� ������������������  (list����������� ������������������  +����������� ������������������  Paging����������� ������������������  Info(totalCount))

•iterate

•count

•singleResult,����������� ������������������  uniqueResult

59

Page 60: QueryDSL - Tistory

단순����������� ������������������  쿼리

����������� ������������������   ����������� ������������������   JPAQuery����������� ������������������  query����������� ������������������  =����������� ������������������  new����������� ������������������  JPAQuery(entityManager);����������� ������������������  ����������� ������������������  ����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  results����������� ������������������  =����������� ������������������  query.from(m)����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   .where(m.name.startsWith("김").and(m.age.between(20,����������� ������������������  40)))����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   .list(m);

60

Page 61: QueryDSL - Tistory

동적����������� ������������������  쿼리����������� ������������������   ����������� ������������������   String����������� ������������������  firstName����������� ������������������  =����������� ������������������  "김";����������� ������������������  int����������� ������������������  min=20,max=40;����������� ������������������   ����������� ������������������  

����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   BooleanBuilder����������� ������������������  builder����������� ������������������  =����������� ������������������  new����������� ������������������  BooleanBuilder();����������� ������������������   ����������� ������������������   if����������� ������������������  (StringUtils.hasText(str))����������� ������������������   ����������� ������������������   ����������� ������������������   builder.and(m.name.startsWith(firstName));����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   if����������� ������������������  (min����������� ������������������  !=����������� ������������������  0����������� ������������������  &&����������� ������������������  max����������� ������������������  !=����������� ������������������  0)����������� ������������������   ����������� ������������������   ����������� ������������������   builder.and(m.age.between(min,����������� ������������������  max));����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  results����������� ������������������  =����������� ������������������  query.from(m).where(builder).list(m);

61

Page 62: QueryDSL - Tistory

조인����������� ������������������  쿼리

����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������   QMemberCard����������� ������������������  mc����������� ������������������  =����������� ������������������  QMemberCard.memberCard;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   query.from(m).join(m.memberCards,����������� ������������������  mc)����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   .list(m);

62

Page 63: QueryDSL - Tistory

조인����������� ������������������  쿼리����������� ������������������  +����������� ������������������  fetch����������� ������������������   ����������� ������������������   QCard����������� ������������������  c����������� ������������������  =����������� ������������������  QCard.card;����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������   QMemberCard����������� ������������������  mc����������� ������������������  =����������� ������������������  QMemberCard.memberCard;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   query.from(m)

����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   .join(m.memberCards,����������� ������������������  mc).fetch()����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   .join(mc.card,����������� ������������������  c).fetch()����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   .list(m);����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   for����������� ������������������  (Member����������� ������������������  member����������� ������������������  :����������� ������������������  list)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������  out.println(member.getMemberCards().get(0).getCard().getName());����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  }

63

Page 64: QueryDSL - Tistory

서브����������� ������������������  쿼리

query.from(m).where(����������� ������������������  ����������� ������������������  m.in(����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  new����������� ������������������  JPASubQuery().from(m)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .where(m.age.between(20,����������� ������������������  40)).list(m))����������� ������������������  ����������� ������������������  ).list(m);

64

Page 65: QueryDSL - Tistory

DTO����������� ������������������   ����������� ������������������   QMember����������� ������������������  $member����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������   QMemberCard����������� ������������������  $memberCard����������� ������������������  =����������� ������������������  QMemberCard.memberCard;����������� ������������������   ����������� ������������������   QCard����������� ������������������  $card����������� ������������������  =����������� ������������������  QCard.card;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<MemberDTO>����������� ������������������  list����������� ������������������  =����������� ������������������  query.from($member)����������� ������������������   ����������� ������������������   ����������� ������������������   .join($member.memberCards,����������� ������������������  $memberCard)����������� ������������������   ����������� ������������������   ����������� ������������������   .join($memberCard.card,����������� ������������������  $card)

����������� ������������������   ����������� ������������������   .list(Projections.bean(MemberDTO.class,,$member.id,$member.name,$member.age,$card.name.as("cardName")

));

public����������� ������������������  class����������� ������������������  MemberDTO����������� ������������������  {����������� ������������������  Long����������� ������������������  id,����������� ������������������  String����������� ������������������  name,����������� ������������������  int����������� ������������������  age,����������� ������������������  String����������� ������������������  cardName����������� ������������������  }

65

Page 66: QueryDSL - Tistory

DTO+@QueryProjection

����������� ������������������   ����������� ������������������   QMember����������� ������������������  $member����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������   QMemberCard����������� ������������������  $memberCard����������� ������������������  =����������� ������������������  QMemberCard.memberCard;����������� ������������������   ����������� ������������������   QCard����������� ������������������  $card����������� ������������������  =����������� ������������������  QCard.card;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<MemberDTO>����������� ������������������  list����������� ������������������  =����������� ������������������  query.from($member)����������� ������������������   ����������� ������������������   ����������� ������������������   .join($member.memberCards,����������� ������������������  $memberCard)����������� ������������������   ����������� ������������������   ����������� ������������������   .join($memberCard.card,����������� ������������������  $card)����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .list(new����������� ������������������  QMemberDTO($member.id,����������� ������������������  $member.name����������� ������������������  ,$member.age����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ,$card.name));

@QueryProjectionpublic����������� ������������������  MemberDTO(Long����������� ������������������  id,����������� ������������������  String����������� ������������������  name,����������� ������������������  int����������� ������������������  age,����������� ������������������  String����������� ������������������  cardName)

66

Page 67: QueryDSL - Tistory

@QueryDelegate

public����������� ������������������  class����������� ������������������  MemberExpression����������� ������������������  {

����������� ������������������   @QueryDelegate(Member.class)

����������� ������������������   public����������� ������������������  static����������� ������������������  BooleanExpression����������� ������������������  isAdult(QMember����������� ������������������  $){����������� ������������������   ����������� ������������������   return����������� ������������������  $.age.gt(20);����������� ������������������   }

����������� ������������������   @QueryDelegate(Member.class)����������� ������������������   public����������� ������������������  static����������� ������������������  BooleanExpression����������� ������������������  isVip(QMember����������� ������������������  $){����������� ������������������   ����������� ������������������   return����������� ������������������  $.age.gt(50);����������� ������������������   }}

����������� ������������������   ����������� ������������������   QMember����������� ������������������  $m����������� ������������������  =����������� ������������������  QMember.member;query.from(m)

.where(m.isAdult())

.list(m);����������� ������������������  ����������� ������������������  

67

Page 68: QueryDSL - Tistory

페이징,����������� ������������������  정렬����������� ������������������   ����������� ������������������   SearchResults<Member>����������� ������������������  listResults����������� ������������������  =����������� ������������������  

query.from(m).offset(0).limit(10).orderBy(m.age.desc())

.listResults(m);

����������� ������������������   ����������� ������������������   System.out.println("total����������� ������������������  count=����������� ������������������  "����������� ������������������  +����������� ������������������  listResults.getTotal());����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  results����������� ������������������  =����������� ������������������  listResults.getResults();

68

Page 69: QueryDSL - Tistory

Spring����������� ������������������  Data����������� ������������������  JPA+����������� ������������������  Querydsl

69

Page 70: QueryDSL - Tistory

Spring����������� ������������������  Data����������� ������������������  목적

•다양한����������� ������������������  Data����������� ������������������  Access를����������� ������������������  스프링과����������� ������������������  통합

•다양한����������� ������������������  Data����������� ������������������  Access를����������� ������������������  쉽게����������� ������������������  개발하도록����������� ������������������  도움

•기타����������� ������������������  등등...

70

Page 71: QueryDSL - Tistory

[Data����������� ������������������  Access����������� ������������������  Layer]JPA

JDBC����������� ������������������  ExtensionApache����������� ������������������  Hadoop

GemFire,����������� ������������������  Redis,����������� ������������������  MongoDB����������� ������������������  ...

Spring����������� ������������������  Data

Spring����������� ������������������  Data����������� ������������������  지원

71

Page 72: QueryDSL - Tistory

Spring����������� ������������������  Data����������� ������������������  JPA����������� ������������������  간략

•JPA기반����������� ������������������  Data����������� ������������������  Access����������� ������������������  Layer����������� ������������������  개발을����������� ������������������  단순화함

72

Page 73: QueryDSL - Tistory

Repository

•인터페이스����������� ������������������  선언����������� ������������������  만으로����������� ������������������  EntityRepository완성����������� ������������������  (Generic)

•구현����������� ������������������  클래스는����������� ������������������  런타임에����������� ������������������  자동으로����������� ������������������  생성됨

����������� ������������������  interface����������� ������������������  MemberRepository����������� ������������������  extends����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  JpaRepository<Member,����������� ������������������  Long>����������� ������������������  {����������� ������������������  }

73

Page 74: QueryDSL - Tistory

����������� ������������������  interface����������� ������������������  MemberRepository����������� ������������������  extends����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  JpaRepository<Member,����������� ������������������  Long>����������� ������������������  {����������� ������������������  }

부모����������� ������������������  Repository

•부모����������� ������������������  Interface

•등록,����������� ������������������  수정,����������� ������������������  삭제

•조회,����������� ������������������  페이징,����������� ������������������  정렬

•이����������� ������������������  모든����������� ������������������  것이����������� ������������������  공짜!

74

Page 75: QueryDSL - Tistory

method����������� ������������������  name����������� ������������������  쿼리����������� ������������������  생성

public����������� ������������������  interface����������� ������������������  MemberRepository����������� ������������������  extends����������� ������������������  JpaRepository<Member,����������� ������������������  Long>{

����������� ������������������  ����������� ������������������  public����������� ������������������  List<Member>����������� ������������������  findByName(String����������� ������������������  name);����������� ������������������  ����������� ������������������  }

•메서드����������� ������������������  이름만����������� ������������������  지어주면����������� ������������������  나머진����������� ������������������  알아서...

•select����������� ������������������  *����������� ������������������  from����������� ������������������  member����������� ������������������  where����������� ������������������  name=:name

75

Page 76: QueryDSL - Tistory

Spring����������� ������������������  Data����������� ������������������  JPA데이터����������� ������������������  조회기능

•method����������� ������������������  name����������� ������������������  쿼리����������� ������������������  생성

•Specfication(DDD)

•QueryDSL

•JPQL����������� ������������������  (이건����������� ������������������  패스)

76

Page 77: QueryDSL - Tistory

method����������� ������������������  name����������� ������������������  쿼리����������� ������������������  생성

����������� ������������������  ����������� ������������������  List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  memberRepository����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .findByNameStartingWithAndAgeBetweenOrderByAgeDesc("김",����������� ������������������  20,����������� ������������������  40);����������� ������������������   ����������� ������������������  

����������� ������������������  public����������� ������������������  interface����������� ������������������  MemberRepository����������� ������������������  ...����������� ������������������  {

����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  List<Member>����������� ������������������  findByNameStartingWithAndAgeBetweenOrderByAgeDesc����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  (String����������� ������������������  string,����������� ������������������  int����������� ������������������  min,����������� ������������������  int����������� ������������������  max);����������� ������������������  }

77

Page 78: QueryDSL - Tistory

method����������� ������������������  name����������� ������������������  쿼리����������� ������������������  생성

•장점����������� ������������������  :����������� ������������������  세상에서����������� ������������������  가장����������� ������������������  심플,����������� ������������������  편리

•단점

•동적쿼리X

•조합이����������� ������������������  불가능����������� ������������������  ->����������� ������������������  메서드가����������� ������������������  무한����������� ������������������  증가

•검색조건이����������� ������������������  많으면����������� ������������������  너무����������� ������������������  길어짐

•결론����������� ������������������  :����������� ������������������  간단한����������� ������������������  것에만����������� ������������������  쓰자

78

Page 79: QueryDSL - Tistory

DDD����������� ������������������  Specification

79

Page 80: QueryDSL - Tistory

Specfication(DDD)

Specification<Member>����������� ������������������  firstNameLike����������� ������������������  =����������� ������������������  MemberSpecs.isFirstName("김");����������� ������������������   Specification<Member>����������� ������������������  ageBetween����������� ������������������  =����������� ������������������  MemberSpecs.ageBetween(20,����������� ������������������  40);����������� ������������������  ����������� ������������������   Specifications<Member>����������� ������������������  specs����������� ������������������  =����������� ������������������  

Specifications.where(firstNameLike).and(ageBetween);����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  memberRepository.findAll(specs);

80

Page 81: QueryDSL - Tistory

����������� ������������������  public����������� ������������������  static����������� ������������������  class����������� ������������������  MemberSpecs����������� ������������������  {

����������� ������������������   public����������� ������������������  static����������� ������������������  Specification<Member>����������� ������������������  isFirstName(final����������� ������������������  String����������� ������������������  firstName){����������� ������������������   ����������� ������������������   return����������� ������������������  new����������� ������������������  Specification<Member>()����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   @Override����������� ������������������   ����������� ������������������   ����������� ������������������   public����������� ������������������  Predicate����������� ������������������  toPredicate(Root<Member>����������� ������������������  root,����������� ������������������  CriteriaQuery<?>����������� ������������������  query,����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   CriteriaBuilder����������� ������������������  cb)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   Path<String>����������� ������������������  namePath����������� ������������������  =����������� ������������������  root.get("name");����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   return����������� ������������������  cb.like(namePath,����������� ������������������  firstName+"%");����������� ������������������   ����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������   };����������� ������������������   }����������� ������������������   public����������� ������������������  static����������� ������������������  Specification<Member>����������� ������������������  ageBetween(final����������� ������������������  int����������� ������������������  min,����������� ������������������  final����������� ������������������  int����������� ������������������  max){����������� ������������������   ����������� ������������������   return����������� ������������������  new����������� ������������������  Specification<Member>()����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   @Override����������� ������������������   ����������� ������������������   ����������� ������������������   public����������� ������������������  Predicate����������� ������������������  toPredicate(Root<Member>����������� ������������������  root,����������� ������������������  CriteriaQuery<?>����������� ������������������  query,����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   CriteriaBuilder����������� ������������������  cb)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   Path<Integer>����������� ������������������  age����������� ������������������  =����������� ������������������  root.get("age");����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   return����������� ������������������  cb.between(age,����������� ������������������  min,����������� ������������������  max);����������� ������������������   ����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������   };����������� ������������������   }����������� ������������������   ����������� ������������������  ����������� ������������������  }

81

Page 82: QueryDSL - Tistory

Specfication(DDD)

•장점

•재사용����������� ������������������  가능,����������� ������������������  조합����������� ������������������  가능

•단점

•JPA����������� ������������������  Criteria����������� ������������������  API����������� ������������������  사용,����������� ������������������  복잡,����������� ������������������  어려움

•type-safe����������� ������������������  아님(MetaModel보완가능)

•복잡한����������� ������������������  Specs..����������� ������������������  배보다����������� ������������������  배꼽이����������� ������������������  큰����������� ������������������  상황

82

Page 83: QueryDSL - Tistory

SpringData����������� ������������������  +����������� ������������������  QueryDSL

����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������  ����������� ������������������   Iterable<Member>����������� ������������������  results����������� ������������������  =����������� ������������������  memberRepository.findAll(����������� ������������������   ����������� ������������������   ����������� ������������������   m.name.startsWith("김").and(m.age.between(20,����������� ������������������  40))����������� ������������������   );

public����������� ������������������  interface����������� ������������������  MemberRepository����������� ������������������  extends����������� ������������������  JpaRepository<Member,����������� ������������������  Long>,

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  QueryDslPredicateExecutor<Member>����������� ������������������  {}

83

Page 84: QueryDSL - Tistory

SpringData����������� ������������������  +����������� ������������������  QueryDSL

•장점

•재사용����������� ������������������  가능,����������� ������������������  조합����������� ������������������  가능

•type-safe

•이건����������� ������������������  써야해!

84

Page 85: QueryDSL - Tistory

이거면����������� ������������������  끝장!

85

Page 86: QueryDSL - Tistory

조인����������� ������������������  쿼리좀����������� ������������������  짜볼까?

86

Page 87: QueryDSL - Tistory

join이����������� ������������������  필요해!

����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   Iterable<Member>����������� ������������������  results����������� ������������������  =����������� ������������������  memberRepository.findAll(����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   m.name.startsWith("김").and(m.age.between(20,����������� ������������������  40))����������� ������������������   ����������� ������������������   );

잉???조인은����������� ������������������  어디에???

87

Page 88: QueryDSL - Tistory

timowest

복잡한����������� ������������������  건����������� ������������������  JPAQuery����������� ������������������  instance를직접����������� ������������������  사용해야����������� ������������������  합니다.

88

Page 89: QueryDSL - Tistory

SpringData����������� ������������������  +����������� ������������������  Querydsl한계

•Querydsl의����������� ������������������  모든����������� ������������������  기능을����������� ������������������  쓸����������� ������������������  수����������� ������������������  없다.

•ex)����������� ������������������  join,����������� ������������������  fetch����������� ������������������  등����������� ������������������  Query기능����������� ������������������  불가능

•subQuery����������� ������������������  정도는����������� ������������������  가능

•페이징,����������� ������������������  Order가����������� ������������������  양쪽이����������� ������������������  조금씩����������� ������������������  다름

89

Page 90: QueryDSL - Tistory

•SpringData프로젝트의����������� ������������������  약점은����������� ������������������  조회

•Querydsl로����������� ������������������  조회����������� ������������������  기능����������� ������������������  보완

SpringData����������� ������������������  +����������� ������������������  Querydsl정리

90

Page 91: QueryDSL - Tistory

SpringData����������� ������������������  +����������� ������������������  Querydsl정리

•단순한����������� ������������������  경우����������� ������������������  :����������� ������������������  SpringData����������� ������������������  +����������� ������������������  Querydsl

•복잡한����������� ������������������  경우����������� ������������������  :����������� ������������������  Querydsl직접����������� ������������������  사용

•SpringData에서����������� ������������������  Querydsl의����������� ������������������  더����������� ������������������  많은����������� ������������������  기능을����������� ������������������  지원하기����������� ������������������  위해����������� ������������������  적극����������� ������������������  노력중

91

Page 92: QueryDSL - Tistory

혹시나����������� ������������������  해서...

•QueryDSL의����������� ������������������  Service����������� ������������������  Layer침투는����������� ������������������  죽어도����������� ������������������  안된다!����������� ������������������  라고����������� ������������������  생각하시면...

•QueryDslRepositorySupport

92

Page 93: QueryDSL - Tistory

혹시나����������� ������������������  해서...

•maven-apt-plugin(1.0.6)����������� ������������������  X

•apt-maven-plugin(1.0.6)����������� ������������������  O

93

Page 94: QueryDSL - Tistory

QueryDSL����������� ������������������  결론

•한번����������� ������������������  써보면����������� ������������������  돌아����������� ������������������  올����������� ������������������  수����������� ������������������  없음

•SpringData����������� ������������������  에서도����������� ������������������  밀고����������� ������������������  있음

•감동의����������� ������������������  컴파일����������� ������������������  에러

•감동의����������� ������������������  ctrl+space,����������� ������������������  Code-assistant

•버그가����������� ������������������  가끔����������� ������������������  있지만����������� ������������������  커미터가����������� ������������������  완전����������� ������������������  열정적

•진짜����������� ������������������  복잡한����������� ������������������  것은����������� ������������������  쌩����������� ������������������  쿼리����������� ������������������  사용

94

Page 95: QueryDSL - Tistory

참고자료

• QueryDSL����������� ������������������  http://www.querydsl.com/

• QueryDSL����������� ������������������  PPT����������� ������������������  http://www.slideshare.net/timowestkamper

• SpringDataJPA����������� ������������������  http://www.springsource.org/spring-data/jpa

• BOOK����������� ������������������  셈플����������� ������������������  소스����������� ������������������  https://github.com/SpringSource/spring-data-book

•조영호님����������� ������������������  블로그,����������� ������������������  DSL설명����������� ������������������  http://aeternum.egloos.com/2962600

95

Page 96: QueryDSL - Tistory

감사합니다.

96

Page 97: QueryDSL - Tistory

추가Querydsl-Collections

Querydsl-SQL

97

Page 98: QueryDSL - Tistory

Querydsl-Java����������� ������������������  Collections

98

Page 99: QueryDSL - Tistory

질문

•사람을����������� ������������������  찾아보자

•20~40살����������� ������������������  중����������� ������������������  성이����������� ������������������  김씨인����������� ������������������  사람을����������� ������������������  찾고����������� ������������������  나이가����������� ������������������  많은����������� ������������������  순서대로����������� ������������������  3명을����������� ������������������  출력하라.

99

Page 100: QueryDSL - Tistory

회원

public����������� ������������������  class����������� ������������������  Member����������� ������������������  {

����������� ������������������   private����������� ������������������  String����������� ������������������  name;����������� ������������������   private����������� ������������������  int����������� ������������������  age;...}

100

Page 101: QueryDSL - Tistory

����������� ������������������   @Test����������� ������������������   public����������� ������������������  void����������� ������������������  java()����������� ������������������  {����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  members����������� ������������������  =����������� ������������������  createDatas();����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  new����������� ������������������  ArrayList<Member>();����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   for����������� ������������������  (Member����������� ������������������  member����������� ������������������  :����������� ������������������  members)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   ����������� ������������������   if(member.getAge()����������� ������������������  >=����������� ������������������  20){����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   if(member.getAge()����������� ������������������  <=����������� ������������������  40){����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   if(member.getName().startsWith("김")){����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   list.add(member);����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   //나이순으로����������� ������������������  정렬...--;����������� ������������������  완전����������� ������������������  길어져서����������� ������������������  생략합니다.����������� ������������������   ����������� ������������������   //3명만����������� ������������������  뽑는����������� ������������������  것도����������� ������������������  생략합니다.����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   for����������� ������������������  (Member����������� ������������������  member����������� ������������������  :����������� ������������������  list)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   System.out.println(member.getName()����������� ������������������  +"/"+����������� ������������������  member.getAge());����������� ������������������   ����������� ������������������   }����������� ������������������   }

101

Page 102: QueryDSL - Tistory

QueryDSL-Collections

Member.java

QMember.java

APT

생성

102

Page 103: QueryDSL - Tistory

회원

@QueryEntitypublic����������� ������������������  class����������� ������������������  Member����������� ������������������  {

����������� ������������������   private����������� ������������������  String����������� ������������������  name;����������� ������������������   private����������� ������������������  int����������� ������������������  age;...}

103

Page 104: QueryDSL - Tistory

@Generated("com.mysema.query.codegen.EntitySerializer")public����������� ������������������  class����������� ������������������  QMember����������� ������������������  extends����������� ������������������  EntityPathBase<Member>����������� ������������������  {

����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  StringPath����������� ������������������  name����������� ������������������  =����������� ������������������  createString("name");����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  NumberPath<Integer>����������� ������������������  age����������� ������������������  =����������� ������������������  

createNumber("age",����������� ������������������  Integer.class);

����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  static����������� ������������������  QMember����������� ������������������  member����������� ������������������  =����������� ������������������  new����������� ������������������  QMember("member");...}

자동생성된����������� ������������������  회원Query

104

Page 105: QueryDSL - Tistory

import����������� ������������������  static����������� ������������������  com.mysema.query.collections.MiniApi.*;

����������� ������������������   @Test����������� ������������������   public����������� ������������������  void����������� ������������������  collectionQuerydsl()����������� ������������������  {����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  members����������� ������������������  =����������� ������������������  createDatas();����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  from(m,����������� ������������������  members).where(����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   m.age.between(20,����������� ������������������  40).and(m.name.like("김%"))����������� ������������������   ����������� ������������������   )����������� ������������������   ����������� ������������������   .orderBy(m.age.desc()).limit(3).list(m);����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   for����������� ������������������  (Member����������� ������������������  member����������� ������������������  :����������� ������������������  list)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   System.out.println(member.getName()����������� ������������������  +"/"+����������� ������������������  member.getAge());����������� ������������������   ����������� ������������������   }����������� ������������������   }

105

Page 106: QueryDSL - Tistory

Java����������� ������������������  Collections����������� ������������������  결론

•좋아����������� ������������������  보입니다!

•하지만...����������� ������������������  현실에선����������� ������������������  DB-SQL로����������� ������������������  끝내야����������� ������������������  하는일

106

Page 107: QueryDSL - Tistory

Querydsl-SQL

107

Page 108: QueryDSL - Tistory

질문

•사람을����������� ������������������  찾아보자

•20~40살����������� ������������������  중����������� ������������������  성이����������� ������������������  김씨인����������� ������������������  사람을����������� ������������������  찾고����������� ������������������  나이가����������� ������������������  많은����������� ������������������  순서대로����������� ������������������  3명을����������� ������������������  출력하라.

108

Page 109: QueryDSL - Tistory

회원

public����������� ������������������  class����������� ������������������  Member����������� ������������������  {

����������� ������������������   private����������� ������������������  Long����������� ������������������  id;����������� ������������������   private����������� ������������������  String����������� ������������������  name;����������� ������������������   private����������� ������������������  int����������� ������������������  age;...}

109

Page 110: QueryDSL - Tistory

회원����������� ������������������  Table

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  create����������� ������������������  table����������� ������������������  Member����������� ������������������  (����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  id����������� ������������������  bigint����������� ������������������  auto����������� ������������������  primary����������� ������������������  key,����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  age����������� ������������������  integer����������� ������������������  not����������� ������������������  null,����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  name����������� ������������������  varchar(255),����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  )

110

Page 111: QueryDSL - Tistory

쿼리만들기select����������� ������������������  m.ID,����������� ������������������  m.AGE,����������� ������������������  m.NAMEfrom����������� ������������������  MEMBER����������� ������������������  mwhere����������� ������������������  m.AGEbetween����������� ������������������  20����������� ������������������  and����������� ������������������  40����������� ������������������  and����������� ������������������  m.NAME����������� ������������������  like����������� ������������������  '김%'order����������� ������������������  by����������� ������������������  m.AGE����������� ������������������  desclimit����������� ������������������  3

111

Page 112: QueryDSL - Tistory

쿼리����������� ������������������  ->����������� ������������������  DTO

이건����������� ������������������  생략할께요--;...

112

Page 113: QueryDSL - Tistory

QueryDSL-SQL

MemberTABLE

QMember.java

생성

querydsl-maven-plugin

113

Page 114: QueryDSL - Tistory

@Generated("com.mysema.query.sql.codegen.MetaDataSerializer")public����������� ������������������  class����������� ������������������  QMember����������� ������������������  extends����������� ������������������  ...RelationalPathBase<Member>����������� ������������������  {

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  static����������� ������������������  final����������� ������������������  QMember����������� ������������������  member����������� ������������������  =����������� ������������������  new����������� ������������������  QMember("MEMBER");

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  NumberPath<Long>����������� ������������������  id����������� ������������������  =����������� ������������������  createNumber("ID",����������� ������������������  Long.class);����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  NumberPath<Integer>����������� ������������������  age����������� ������������������  =����������� ������������������  createNumber("AGE",����������� ������������������  Integer.class);����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  public����������� ������������������  final����������� ������������������  StringPath����������� ������������������  name����������� ������������������  =����������� ������������������  createString("NAME");

...}

자동생성된����������� ������������������  회원Query

114

Page 115: QueryDSL - Tistory

����������� ������������������   @Test����������� ������������������   public����������� ������������������  void����������� ������������������  sqlQuerydsl()����������� ������������������  throws����������� ������������������  Exception����������� ������������������  {

����������� ������������������   ����������� ������������������   SQLQuery����������� ������������������  query����������� ������������������  =����������� ������������������  createQuery();����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   QMember����������� ������������������  m����������� ������������������  =����������� ������������������  QMember.member;����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   List<MemberDTO>����������� ������������������  list����������� ������������������  =����������� ������������������  query.from(m).where(����������� ������������������   ����������� ������������������   ����������� ������������������   ����������� ������������������   m.age.between(20,����������� ������������������  40).and(m.name.like("김%"))����������� ������������������   ����������� ������������������   )����������� ������������������   ����������� ������������������   .orderBy(m.age.desc()).limit(3)����������� ������������������   ����������� ������������������   .list(Projections.bean(MemberDTO.class,����������� ������������������  m.id,����������� ������������������  m.name,����������� ������������������  m.age);����������� ������������������   ����������� ������������������  ����������� ������������������   ����������� ������������������   for����������� ������������������  (MemberDTO����������� ������������������  member����������� ������������������  :����������� ������������������  list)����������� ������������������  {����������� ������������������   ����������� ������������������   ����������� ������������������   System.out.println(member);����������� ������������������   ����������� ������������������   }����������� ������������������   ����������� ������������������  ����������� ������������������   }

����������� ������������������   private����������� ������������������  SQLQuery����������� ������������������  createQuery()����������� ������������������  throws����������� ������������������  Exception����������� ������������������  {����������� ������������������   ����������� ������������������   Class.forName("net.sf.log4jdbc.DriverSpy");����������� ������������������   ����������� ������������������   Connection����������� ������������������  conn����������� ������������������  =����������� ������������������  DriverManager.getConnection("jdbc:log4jdbc:hsqldb:hsql://localhost");����������� ������������������   ����������� ������������������   SQLTemplates����������� ������������������  dialect����������� ������������������  =����������� ������������������  new����������� ������������������  HSQLDBTemplates();����������� ������������������   ����������� ������������������   SQLQuery����������� ������������������  query����������� ������������������  =����������� ������������������  new����������� ������������������  SQLQueryImpl(conn,����������� ������������������  dialect);����������� ������������������   ����������� ������������������   return����������� ������������������  query;����������� ������������������   }

115

Page 116: QueryDSL - Tistory

자동����������� ������������������  생성된����������� ������������������  쿼리select����������� ������������������  m.ID,����������� ������������������  m.AGE,����������� ������������������  m.NAMEfrom����������� ������������������  MEMBER����������� ������������������  mwhere����������� ������������������  m.AGEbetween����������� ������������������  20����������� ������������������  and����������� ������������������  40����������� ������������������  and����������� ������������������  m.NAME����������� ������������������  like����������� ������������������  '김%'order����������� ������������������  by����������� ������������������  m.AGE����������� ������������������  desclimit����������� ������������������  3

116

Page 117: QueryDSL - Tistory

Querydsl-SQL����������� ������������������  조금더

•innerJoin,����������� ������������������  join,����������� ������������������  leftJoin,����������� ������������������  fullJoin

•groupBy

•having

•orderBy

•subquery

•insert,����������� ������������������  update,����������� ������������������  delete

117

Page 118: QueryDSL - Tistory

Querydsl-SQL����������� ������������������  조금더QSurvey����������� ������������������  survey����������� ������������������  =����������� ������������������  QSurvey.survey;����������� ������������������  ����������� ������������������  new����������� ������������������  SQLInsertClause(conn,����������� ������������������  dialect,����������� ������������������  survey)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .columns(survey.id,����������� ������������������  survey.name)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .values(3,����������� ������������������  "Hello").execute();

QSurvey����������� ������������������  survey����������� ������������������  =����������� ������������������  QSurvey.survey;

new����������� ������������������  SQLUpdateClause(conn,����������� ������������������  dialect,����������� ������������������  survey)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .where(survey.name.eq("XXX"))����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .set(survey.name,����������� ������������������  "S")����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .execute();

QSurvey����������� ������������������  survey����������� ������������������  =����������� ������������������  QSurvey.survey;

new����������� ������������������  SQLDelecteClause(conn,����������� ������������������  dialect,����������� ������������������  survey)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .where(survey.name.eq("XXX"))����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .execute();

QCustomer����������� ������������������  customer����������� ������������������  =����������� ������������������  QCustomer.customer;QCompany����������� ������������������  company����������� ������������������  =����������� ������������������  QCompany.company;query.from(customer)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .innerJoin(customer.company,����������� ������������������  company)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  .list(customer.firstName,����������� ������������������  customer.lastName,����������� ������������������  company.name);

118

Page 119: QueryDSL - Tistory

DTO자동����������� ������������������  생성����������� ������������������  기능

•옵션만����������� ������������������  키면����������� ������������������  DTO도����������� ������������������  자동����������� ������������������  생성����������� ������������������  가능

•MEMBER����������� ������������������  TABLE����������� ������������������  ->����������� ������������������  MEMBER.java

119

Page 120: QueryDSL - Tistory

DTO자동����������� ������������������  생성����������� ������������������  기능하지만...

•DTO에����������� ������������������  연관관계는����������� ������������������  만들어지지����������� ������������������  않음

•TABLE->DTO����������� ������������������  자동����������� ������������������  생성은����������� ������������������  1:1����������� ������������������  인����������� ������������������  경우만����������� ������������������  쓸만함

•DTO����������� ������������������  를����������� ������������������  수정����������� ������������������  할����������� ������������������  수����������� ������������������  없다.

•Querydsl은����������� ������������������  ORM이����������� ������������������  아님

120

Page 121: QueryDSL - Tistory

Querydsl-SQL����������� ������������������  결론

•장점����������� ������������������  :����������� ������������������  type-safe

•주의점����������� ������������������  :����������� ������������������  FK를����������� ������������������  명확하게����������� ������������������  설정해야����������� ������������������  한다.

121


Recommended