querydsl - tistory
Post on 20-Oct-2021
15 Views
Preview:
TRANSCRIPT
QueryDSLtype-safe����������� ������������������ Query
발표자����������� ������������������ :����������� ������������������ 김영한
1
목차
•문제
•JPA����������� ������������������ Query
•QueryDSL?
•QueryDSL-JPA
•기능����������� ������������������ 살펴보기
•Spring����������� ������������������ Data����������� ������������������ JPA����������� ������������������ +����������� ������������������ Querydsl
2
문제
3
긴급����������� ������������������ 요구사항
•검색조건����������� ������������������ 추가
•나이
•이름
•퇴근시간����������� ������������������ 10분전...
4
기능����������� ������������������ 추가
이정도는 발로 만들어 주지
5
쿼리����������� ������������������ 추가
String����������� ������������������ sql����������� ������������������ =
“select����������� ������������������ *����������� ������������������ from����������� ������������������ member”����������� ������������������ +
“where����������� ������������������ name����������� ������������������ like����������� ������������������ ?”����������� ������������������ +
“and����������� ������������������ age����������� ������������������ between����������� ������������������ ?����������� ������������������ and����������� ������������������ ?”
6
컴파일����������� ������������������ 완료
7
배포����������� ������������������ 완료
8
퇴근����������� ������������������ 완료
9
버그����������� ������������������ 발생
10
리콜����������� ������������������ 완료??
그럴리가����������� ������������������ 없어분명����������� ������������������ 빌드는����������� ������������������ 성공했어!
11
버그String����������� ������������������ sql����������� ������������������ =
“select����������� ������������������ *����������� ������������������ from����������� ������������������ member”����������� ������������������ +
“where����������� ������������������ name����������� ������������������ like����������� ������������������ ?”����������� ������������������ +
“and����������� ������������������ age����������� ������������������ between����������� ������������������ ?����������� ������������������ and����������� ������������������ ?”
[합치면]
“select����������� ������������������ *����������� ������������������ from����������� ������������������ memberwhere����������� ������������������ name����������� ������������������ like����������� ������������������ ?and����������� ������������������ age����������� ������������������ between����������� ������������������ ?����������� ������������������ and����������� ������������������ ?”
12
QUERY의����������� ������������������ 문제점
•QUERY는����������� ������������������ 문자,����������� ������������������ Type-check����������� ������������������ 불가능
•실행해����������� ������������������ 보기����������� ������������������ 전까지����������� ������������������ 작동여부����������� ������������������ 확인����������� ������������������ 불가
13
에러는����������� ������������������ 크게����������� ������������������ 2가지
•컴파일����������� ������������������ 에러����������� ������������������ (좋은����������� ������������������ 에러)
•런타임����������� ������������������ 에러����������� ������������������ (나쁜����������� ������������������ 에러)
14
도메인����������� ������������������ 고수?
전����������� ������������������ SQL을����������� ������������������ 빨리����������� ������������������ 작성하기����������� ������������������ 위해����������� ������������������ 컬럼명����������� ������������������ 정도는����������� ������������������ 모두����������� ������������������
외운답니다.
SELECT����������� ������������������ NAME,����������� ������������������ AGE����������� ������������������ ..
15
SQL...
•만약����������� ������������������ SQL이����������� ������������������ Class처럼����������� ������������������ Type이����������� ������������������ 있고����������� ������������������ Java코드로����������� ������������������ 작성����������� ������������������ 할����������� ������������������ 수����������� ������������������ 있다면?
•type-safe
16
Type-safe
•컴파일시����������� ������������������ 에러����������� ������������������ 체크����������� ������������������ 가능
•Code-assistant����������� ������������������ x����������� ������������������ 100!!!
•CTRL����������� ������������������ +����������� ������������������ SPACE����������� ������������������ +����������� ������������������ .����������� ������������������ (DOT)
17
QueryDSL-SQL
•SQL을����������� ������������������ Java����������� ������������������ 로����������� ������������������ type-safe하게����������� ������������������ 개발����������� ������������������ 할����������� ������������������ 수����������� ������������������ 있는����������� ������������������ 프레임워크
18
QueryDSL-SQL
19
QueryDSL
•하지만����������� ������������������ 지금은����������� ������������������ ORM시대????
20
JPA����������� ������������������ Queryjava����������� ������������������ ORM
21
질문����������� ������������������ :����������� ������������������ 사람을����������� ������������������ 찾아보자
•20~40살
•성����������� ������������������ =����������� ������������������ 김씨
•나이����������� ������������������ 많은����������� ������������������ 순서
•3명을����������� ������������������ 출력하라.
22
회원@Entitypublic����������� ������������������ class����������� ������������������ Member����������� ������������������ {
����������� ������������������ @Id����������� ������������������ @GeneratedValue����������� ������������������ private����������� ������������������ Long����������� ������������������ id;����������� ������������������ private����������� ������������������ String����������� ������������������ name;����������� ������������������ private����������� ������������������ int����������� ������������������ age;...}
23
회원����������� ������������������ Table
����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ create����������� ������������������ table����������� ������������������ Member����������� ������������������ (����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ id����������� ������������������ bigint����������� ������������������ auto����������� ������������������ primary����������� ������������������ key,����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ age����������� ������������������ integer����������� ������������������ not����������� ������������������ null,����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ name����������� ������������������ varchar(255)����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ )
24
JPA����������� ������������������ 에서����������� ������������������ QUERY����������� ������������������ 방법은크게����������� ������������������ 3가지
•1.����������� ������������������ JPQL(HQL)
•2.����������� ������������������ Criteria����������� ������������������ API
•3.����������� ������������������ MetaModel����������� ������������������ Criteria����������� ������������������ API(type-safe)
25
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
1.����������� ������������������ JPQL(HQL)
•장점����������� ������������������ :����������� ������������������ SQL����������� ������������������ QUERY와����������� ������������������ 비슷해서����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ 금방����������� ������������������ 익숙해짐
•단점����������� ������������������ :����������� ������������������ type-safe����������� ������������������ 아님����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ 동적쿼리����������� ������������������ 생성이����������� ������������������ 어려움
27
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
2.����������� ������������������ Criteria����������� ������������������ API
29
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
2.����������� ������������������ Criteria����������� ������������������ API
•장점����������� ������������������ :����������� ������������������ 동적쿼리����������� ������������������ 생성이����������� ������������������ 쉬움??
•단점
•1.����������� ������������������ type-safe����������� ������������������ 아님
•2.����������� ������������������ 복잡함
•3.����������� ������������������ 알아야����������� ������������������ 할게����������� ������������������ 너무����������� ������������������ 많음
•4.����������� ������������������ 과거����������� ������������������ EJB공부����������� ������������������ 할����������� ������������������ 때가����������� ������������������ 생각남...
31
3.����������� ������������������ MetaModel����������� ������������������ Criteria����������� ������������������ API(type-safe)
•root.get("age")����������� ������������������ ->����������� ������������������ root.get(Member_.age)
•Criteria����������� ������������������ API����������� ������������������ +����������� ������������������ MetaModel
•Criteria����������� ������������������ API와����������� ������������������ 거의����������� ������������������ 동일
•type-safe
•복잡하긴����������� ������������������ 마찬가지
32
이건����������� ������������������ 아니야--;timowest
33
QueryDSL
34
QueryDSL����������� ������������������ 분석
•Query����������� ������������������ :����������� ������������������ 문의,����������� ������������������ 조회,����������� ������������������ 질문,����������� ������������������ ?
•Query����������� ������������������ !=����������� ������������������ SQL
35
QueryDSL����������� ������������������ 분석
•Domain(도메인)
•Specific(특화)
•Language(언어)
36
DSL
•도메인����������� ������������������ +����������� ������������������ 특화����������� ������������������ +����������� ������������������ 언어
•특정한����������� ������������������ 도메인에����������� ������������������ 초점을����������� ������������������ 맞춘����������� ������������������ 제한적인����������� ������������������ 표현력을����������� ������������������ 가진����������� ������������������ 컴퓨터����������� ������������������ 프로그래밍����������� ������������������ 언어
•특징����������� ������������������ :����������� ������������������ 단순,����������� ������������������ 간결,����������� ������������������ 유창
37
QueryDSL
•조회����������� ������������������ +����������� ������������������ 도메인����������� ������������������ +����������� ������������������ 특화����������� ������������������ +����������� ������������������ 언어
•조회에����������� ������������������ 특화된����������� ������������������ 프로그래밍����������� ������������������ 언어
38
[Persistence]JPA,����������� ������������������ JDO,����������� ������������������ SQL,����������� ������������������ JAVA����������� ������������������ Collections,����������� ������������������ RDF,����������� ������������������ Lucene,����������� ������������������ Hibernate����������� ������������������ Search,����������� ������������������
Mongo����������� ������������������ Db
QueryDSL����������� ������������������ API
데이터����������� ������������������ 조회����������� ������������������ 기능����������� ������������������ 추상화
39
QueryDSL?
•type-safe
•조회에����������� ������������������ 특화된����������� ������������������ 프로그래밍����������� ������������������ 언어
•단순,����������� ������������������ 간결,����������� ������������������ 유창
•다양한����������� ������������������ 저장소����������� ������������������ 조회����������� ������������������ 기능����������� ������������������ 통합
40
QueryDSL?
•JPA,����������� ������������������ JDO,����������� ������������������ SQL����������� ������������������ 같은����������� ������������������ Backends를����������� ������������������ 위해����������� ������������������ type-safe����������� ������������������ SQL을����������� ������������������ 만드는����������� ������������������ 프레임워크
41
Type-safeQuery����������� ������������������ Type����������� ������������������ 생성
Member javaMember table
Member ...
QMEMBER.java
코드생성기
생성
42
코드생성기
•APT����������� ������������������ :����������� ������������������ Annotation����������� ������������������ Processing����������� ������������������ Tool
•@Deprecated
•@Override
•@SuppressWarning
•@Entity
•Table����������� ������������������ Meta����������� ������������������ :����������� ������������������ Querydsl-maven-plugin
43
QueryDSL-JPA
44
Querydsl-JPA
•Querydsl은����������� ������������������ JPQL(HQL)을����������� ������������������ typesafe����������� ������������������ 하게����������� ������������������ 작성하기����������� ������������������ 위해����������� ������������������ 만들어짐
•너를����������� ������������������ 위해����������� ������������������ 만들었다!
45
질문����������� ������������������ :����������� ������������������ 사람을����������� ������������������ 찾아보자
•20~40살
•성����������� ������������������ =����������� ������������������ 김씨
•나이����������� ������������������ 많은����������� ������������������ 순서
•3명을����������� ������������������ 출력하라.
46
회원����������� ������������������ Table
����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ create����������� ������������������ table����������� ������������������ Member����������� ������������������ (����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ id����������� ������������������ bigint����������� ������������������ auto����������� ������������������ primary����������� ������������������ key,����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ age����������� ������������������ integer����������� ������������������ not����������� ������������������ null,����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ name����������� ������������������ varchar(255)����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ )
47
회원@Entitypublic����������� ������������������ class����������� ������������������ Member����������� ������������������ {
����������� ������������������ @Id����������� ������������������ @GeneratedValue����������� ������������������ private����������� ������������������ Long����������� ������������������ id;����������� ������������������ private����������� ������������������ String����������� ������������������ name;����������� ������������������ private����������� ������������������ int����������� ������������������ age;...}
48
QueryDSL-JPA
Member.java@Entity
QMember.java
APT
생성
49
@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
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
����������� ������������������ ����������� ������������������ 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
생성된����������� ������������������ 쿼리
����������� ������������������ select����������� ������������������ id,����������� ������������������ age,����������� ������������������ name����������� ������������������ from����������� ������������������ MEMBER����������� ������������������ where����������� ������������������ age����������� ������������������ between����������� ������������������ 20����������� ������������������ and����������� ������������������ 40����������� ������������������ ����������� ������������������ and����������� ������������������ name����������� ������������������ like����������� ������������������ '김%'����������� ������������������ order����������� ������������������ by����������� ������������������ age����������� ������������������ desc����������� ������������������ limit����������� ������������������ 3
53
작동����������� ������������������ 방식
SQLJPQLQUERYDSL
생성 생성
54
Querydsl-JPA•장점
•type-safe
•단순함
•쉬움
•EJB->Spring����������� ������������������ 정도의����������� ������������������ 차이?
•단점
•APT를����������� ������������������ 설정해야함
55
기능����������� ������������������ 살펴보기QueryDSL-JPA
56
구성Query
ex)����������� ������������������ from,����������� ������������������ where,����������� ������������������ join
Path
ex)����������� ������������������ QMember,����������� ������������������ QMember.name
Expression
ex)����������� ������������������ name.eq,����������� ������������������ name.gt
57
기능����������� ������������������ 살펴보기
•from
•innerJoin,����������� ������������������ join,����������� ������������������ leftJoin,����������� ������������������ fullJoin,����������� ������������������ on
•where����������� ������������������ (and,����������� ������������������ or,����������� ������������������ allOf,����������� ������������������ anyOf)
•groupBy
•having
•orderBy����������� ������������������ (desc,����������� ������������������ asc)
•limit,����������� ������������������ offset,����������� ������������������ restrict(limit����������� ������������������ +����������� ������������������ offset)����������� ������������������ (Paging)
58
기능����������� ������������������ 살펴보기
•list
•listResults����������� ������������������ (list����������� ������������������ +����������� ������������������ Paging����������� ������������������ Info(totalCount))
•iterate
•count
•singleResult,����������� ������������������ uniqueResult
59
단순����������� ������������������ 쿼리
����������� ������������������ ����������� ������������������ 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
동적����������� ������������������ 쿼리����������� ������������������ ����������� ������������������ 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
조인����������� ������������������ 쿼리
����������� ������������������ ����������� ������������������ QMember����������� ������������������ m����������� ������������������ =����������� ������������������ QMember.member;����������� ������������������ ����������� ������������������ QMemberCard����������� ������������������ mc����������� ������������������ =����������� ������������������ QMemberCard.memberCard;����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ List<Member>����������� ������������������ list����������� ������������������ =����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ query.from(m).join(m.memberCards,����������� ������������������ mc)����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ .list(m);
62
조인����������� ������������������ 쿼리����������� ������������������ +����������� ������������������ 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
서브����������� ������������������ 쿼리
query.from(m).where(����������� ������������������ ����������� ������������������ m.in(����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ new����������� ������������������ JPASubQuery().from(m)����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ .where(m.age.between(20,����������� ������������������ 40)).list(m))����������� ������������������ ����������� ������������������ ).list(m);
64
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
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
@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
페이징,����������� ������������������ 정렬����������� ������������������ ����������� ������������������ 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
Spring����������� ������������������ Data����������� ������������������ JPA+����������� ������������������ Querydsl
69
Spring����������� ������������������ Data����������� ������������������ 목적
•다양한����������� ������������������ Data����������� ������������������ Access를����������� ������������������ 스프링과����������� ������������������ 통합
•다양한����������� ������������������ Data����������� ������������������ Access를����������� ������������������ 쉽게����������� ������������������ 개발하도록����������� ������������������ 도움
•기타����������� ������������������ 등등...
70
[Data����������� ������������������ Access����������� ������������������ Layer]JPA
JDBC����������� ������������������ ExtensionApache����������� ������������������ Hadoop
GemFire,����������� ������������������ Redis,����������� ������������������ MongoDB����������� ������������������ ...
Spring����������� ������������������ Data
Spring����������� ������������������ Data����������� ������������������ 지원
71
Spring����������� ������������������ Data����������� ������������������ JPA����������� ������������������ 간략
•JPA기반����������� ������������������ Data����������� ������������������ Access����������� ������������������ Layer����������� ������������������ 개발을����������� ������������������ 단순화함
72
Repository
•인터페이스����������� ������������������ 선언����������� ������������������ 만으로����������� ������������������ EntityRepository완성����������� ������������������ (Generic)
•구현����������� ������������������ 클래스는����������� ������������������ 런타임에����������� ������������������ 자동으로����������� ������������������ 생성됨
����������� ������������������ interface����������� ������������������ MemberRepository����������� ������������������ extends����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ JpaRepository<Member,����������� ������������������ Long>����������� ������������������ {����������� ������������������ }
73
����������� ������������������ interface����������� ������������������ MemberRepository����������� ������������������ extends����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ JpaRepository<Member,����������� ������������������ Long>����������� ������������������ {����������� ������������������ }
부모����������� ������������������ Repository
•부모����������� ������������������ Interface
•등록,����������� ������������������ 수정,����������� ������������������ 삭제
•조회,����������� ������������������ 페이징,����������� ������������������ 정렬
•이����������� ������������������ 모든����������� ������������������ 것이����������� ������������������ 공짜!
74
method����������� ������������������ name����������� ������������������ 쿼리����������� ������������������ 생성
public����������� ������������������ interface����������� ������������������ MemberRepository����������� ������������������ extends����������� ������������������ JpaRepository<Member,����������� ������������������ Long>{
����������� ������������������ ����������� ������������������ public����������� ������������������ List<Member>����������� ������������������ findByName(String����������� ������������������ name);����������� ������������������ ����������� ������������������ }
•메서드����������� ������������������ 이름만����������� ������������������ 지어주면����������� ������������������ 나머진����������� ������������������ 알아서...
•select����������� ������������������ *����������� ������������������ from����������� ������������������ member����������� ������������������ where����������� ������������������ name=:name
75
Spring����������� ������������������ Data����������� ������������������ JPA데이터����������� ������������������ 조회기능
•method����������� ������������������ name����������� ������������������ 쿼리����������� ������������������ 생성
•Specfication(DDD)
•QueryDSL
•JPQL����������� ������������������ (이건����������� ������������������ 패스)
76
method����������� ������������������ name����������� ������������������ 쿼리����������� ������������������ 생성
����������� ������������������ ����������� ������������������ List<Member>����������� ������������������ list����������� ������������������ =����������� ������������������ memberRepository����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ .findByNameStartingWithAndAgeBetweenOrderByAgeDesc("김",����������� ������������������ 20,����������� ������������������ 40);����������� ������������������ ����������� ������������������
����������� ������������������ public����������� ������������������ interface����������� ������������������ MemberRepository����������� ������������������ ...����������� ������������������ {
����������� ������������������ ����������� ������������������ ����������� ������������������ public����������� ������������������ List<Member>����������� ������������������ findByNameStartingWithAndAgeBetweenOrderByAgeDesc����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ (String����������� ������������������ string,����������� ������������������ int����������� ������������������ min,����������� ������������������ int����������� ������������������ max);����������� ������������������ }
77
method����������� ������������������ name����������� ������������������ 쿼리����������� ������������������ 생성
•장점����������� ������������������ :����������� ������������������ 세상에서����������� ������������������ 가장����������� ������������������ 심플,����������� ������������������ 편리
•단점
•동적쿼리X
•조합이����������� ������������������ 불가능����������� ������������������ ->����������� ������������������ 메서드가����������� ������������������ 무한����������� ������������������ 증가
•검색조건이����������� ������������������ 많으면����������� ������������������ 너무����������� ������������������ 길어짐
•결론����������� ������������������ :����������� ������������������ 간단한����������� ������������������ 것에만����������� ������������������ 쓰자
78
DDD����������� ������������������ Specification
79
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
����������� ������������������ 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
Specfication(DDD)
•장점
•재사용����������� ������������������ 가능,����������� ������������������ 조합����������� ������������������ 가능
•단점
•JPA����������� ������������������ Criteria����������� ������������������ API����������� ������������������ 사용,����������� ������������������ 복잡,����������� ������������������ 어려움
•type-safe����������� ������������������ 아님(MetaModel보완가능)
•복잡한����������� ������������������ Specs..����������� ������������������ 배보다����������� ������������������ 배꼽이����������� ������������������ 큰����������� ������������������ 상황
82
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
SpringData����������� ������������������ +����������� ������������������ QueryDSL
•장점
•재사용����������� ������������������ 가능,����������� ������������������ 조합����������� ������������������ 가능
•type-safe
•이건����������� ������������������ 써야해!
84
이거면����������� ������������������ 끝장!
85
조인����������� ������������������ 쿼리좀����������� ������������������ 짜볼까?
86
join이����������� ������������������ 필요해!
����������� ������������������ ����������� ������������������ QMember����������� ������������������ m����������� ������������������ =����������� ������������������ QMember.member;����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ Iterable<Member>����������� ������������������ results����������� ������������������ =����������� ������������������ memberRepository.findAll(����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ m.name.startsWith("김").and(m.age.between(20,����������� ������������������ 40))����������� ������������������ ����������� ������������������ );
잉???조인은����������� ������������������ 어디에???
87
timowest
복잡한����������� ������������������ 건����������� ������������������ JPAQuery����������� ������������������ instance를직접����������� ������������������ 사용해야����������� ������������������ 합니다.
88
SpringData����������� ������������������ +����������� ������������������ Querydsl한계
•Querydsl의����������� ������������������ 모든����������� ������������������ 기능을����������� ������������������ 쓸����������� ������������������ 수����������� ������������������ 없다.
•ex)����������� ������������������ join,����������� ������������������ fetch����������� ������������������ 등����������� ������������������ Query기능����������� ������������������ 불가능
•subQuery����������� ������������������ 정도는����������� ������������������ 가능
•페이징,����������� ������������������ Order가����������� ������������������ 양쪽이����������� ������������������ 조금씩����������� ������������������ 다름
89
•SpringData프로젝트의����������� ������������������ 약점은����������� ������������������ 조회
•Querydsl로����������� ������������������ 조회����������� ������������������ 기능����������� ������������������ 보완
SpringData����������� ������������������ +����������� ������������������ Querydsl정리
90
SpringData����������� ������������������ +����������� ������������������ Querydsl정리
•단순한����������� ������������������ 경우����������� ������������������ :����������� ������������������ SpringData����������� ������������������ +����������� ������������������ Querydsl
•복잡한����������� ������������������ 경우����������� ������������������ :����������� ������������������ Querydsl직접����������� ������������������ 사용
•SpringData에서����������� ������������������ Querydsl의����������� ������������������ 더����������� ������������������ 많은����������� ������������������ 기능을����������� ������������������ 지원하기����������� ������������������ 위해����������� ������������������ 적극����������� ������������������ 노력중
91
혹시나����������� ������������������ 해서...
•QueryDSL의����������� ������������������ Service����������� ������������������ Layer침투는����������� ������������������ 죽어도����������� ������������������ 안된다!����������� ������������������ 라고����������� ������������������ 생각하시면...
•QueryDslRepositorySupport
92
혹시나����������� ������������������ 해서...
•maven-apt-plugin(1.0.6)����������� ������������������ X
•apt-maven-plugin(1.0.6)����������� ������������������ O
93
QueryDSL����������� ������������������ 결론
•한번����������� ������������������ 써보면����������� ������������������ 돌아����������� ������������������ 올����������� ������������������ 수����������� ������������������ 없음
•SpringData����������� ������������������ 에서도����������� ������������������ 밀고����������� ������������������ 있음
•감동의����������� ������������������ 컴파일����������� ������������������ 에러
•감동의����������� ������������������ ctrl+space,����������� ������������������ Code-assistant
•버그가����������� ������������������ 가끔����������� ������������������ 있지만����������� ������������������ 커미터가����������� ������������������ 완전����������� ������������������ 열정적
•진짜����������� ������������������ 복잡한����������� ������������������ 것은����������� ������������������ 쌩����������� ������������������ 쿼리����������� ������������������ 사용
94
참고자료
• 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
감사합니다.
96
추가Querydsl-Collections
Querydsl-SQL
97
Querydsl-Java����������� ������������������ Collections
98
질문
•사람을����������� ������������������ 찾아보자
•20~40살����������� ������������������ 중����������� ������������������ 성이����������� ������������������ 김씨인����������� ������������������ 사람을����������� ������������������ 찾고����������� ������������������ 나이가����������� ������������������ 많은����������� ������������������ 순서대로����������� ������������������ 3명을����������� ������������������ 출력하라.
99
회원
public����������� ������������������ class����������� ������������������ Member����������� ������������������ {
����������� ������������������ private����������� ������������������ String����������� ������������������ name;����������� ������������������ private����������� ������������������ int����������� ������������������ age;...}
100
����������� ������������������ @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
QueryDSL-Collections
Member.java
QMember.java
APT
생성
102
회원
@QueryEntitypublic����������� ������������������ class����������� ������������������ Member����������� ������������������ {
����������� ������������������ private����������� ������������������ String����������� ������������������ name;����������� ������������������ private����������� ������������������ int����������� ������������������ age;...}
103
@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
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
Java����������� ������������������ Collections����������� ������������������ 결론
•좋아����������� ������������������ 보입니다!
•하지만...����������� ������������������ 현실에선����������� ������������������ DB-SQL로����������� ������������������ 끝내야����������� ������������������ 하는일
106
Querydsl-SQL
107
질문
•사람을����������� ������������������ 찾아보자
•20~40살����������� ������������������ 중����������� ������������������ 성이����������� ������������������ 김씨인����������� ������������������ 사람을����������� ������������������ 찾고����������� ������������������ 나이가����������� ������������������ 많은����������� ������������������ 순서대로����������� ������������������ 3명을����������� ������������������ 출력하라.
108
회원
public����������� ������������������ class����������� ������������������ Member����������� ������������������ {
����������� ������������������ private����������� ������������������ Long����������� ������������������ id;����������� ������������������ private����������� ������������������ String����������� ������������������ name;����������� ������������������ private����������� ������������������ int����������� ������������������ age;...}
109
회원����������� ������������������ Table
����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ create����������� ������������������ table����������� ������������������ Member����������� ������������������ (����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ id����������� ������������������ bigint����������� ������������������ auto����������� ������������������ primary����������� ������������������ key,����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ age����������� ������������������ integer����������� ������������������ not����������� ������������������ null,����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ name����������� ������������������ varchar(255),����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ )
110
쿼리만들기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
쿼리����������� ������������������ ->����������� ������������������ DTO
이건����������� ������������������ 생략할께요--;...
112
QueryDSL-SQL
MemberTABLE
QMember.java
생성
querydsl-maven-plugin
113
@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
����������� ������������������ @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
자동����������� ������������������ 생성된����������� ������������������ 쿼리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
Querydsl-SQL����������� ������������������ 조금더
•innerJoin,����������� ������������������ join,����������� ������������������ leftJoin,����������� ������������������ fullJoin
•groupBy
•having
•orderBy
•subquery
•insert,����������� ������������������ update,����������� ������������������ delete
117
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
DTO자동����������� ������������������ 생성����������� ������������������ 기능
•옵션만����������� ������������������ 키면����������� ������������������ DTO도����������� ������������������ 자동����������� ������������������ 생성����������� ������������������ 가능
•MEMBER����������� ������������������ TABLE����������� ������������������ ->����������� ������������������ MEMBER.java
119
DTO자동����������� ������������������ 생성����������� ������������������ 기능하지만...
•DTO에����������� ������������������ 연관관계는����������� ������������������ 만들어지지����������� ������������������ 않음
•TABLE->DTO����������� ������������������ 자동����������� ������������������ 생성은����������� ������������������ 1:1����������� ������������������ 인����������� ������������������ 경우만����������� ������������������ 쓸만함
•DTO����������� ������������������ 를����������� ������������������ 수정����������� ������������������ 할����������� ������������������ 수����������� ������������������ 없다.
•Querydsl은����������� ������������������ ORM이����������� ������������������ 아님
120
Querydsl-SQL����������� ������������������ 결론
•장점����������� ������������������ :����������� ������������������ type-safe
•주의점����������� ������������������ :����������� ������������������ FK를����������� ������������������ 명확하게����������� ������������������ 설정해야����������� ������������������ 한다.
121
top related