JPQL : 객체지향쿼리
- SQL을 추상화한 JPA의 객체지향 쿼리
- 테이블이 아닌 엔티티 객체를 대상으로 쿼리
- 엔티티와 속성은 대소문자 구분
- 테이블 이름이 아닌 엔티티 이름 사용
- 별칭(alias) 사용 필수
1. EntityManager 사용시
select alias 시 전체 조회 (sql 에서 a.* 와 같음)
변수바인딩은 :이름 혹은 ?시퀀스 로 할 수 있다
1
2
3
4
5
6
7
8
9
10
11
12
|
@Autowired
EntityManager em;
User user = new User();
user.setName("pyo");
userRepository.save(user);
TypedQuery<User> tq = em.createQuery("select u from User u where u.name = :name", User.class);
tq.setParameter("name", "pyo");
List<User> rs = tq.getResultList();
LOGGER.info("id : " + rs.get(0).getId());
|
cs |
2. repository interface 사용시
@Query를 사용해서 직접 JPQL 지정
이름을 사용한 바인딩시 @Param("이름") 을 사용하지 않을 경우 에러가 발생하니 주의
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public interface UserRepository extends JpaRepository<User, Long>{
List<User> findByName(String name);
User findById(long id);
@Query("select u from User u where u.name = ?1")
User customFind1(String nm);
@Query("select u from User u where u.name = :name")
User customFind2(@Param("name") String nm);
}
|
cs |
JPQL , SQL 의 문제점
- JPQL 은 문자(String)이며, Type-Check가 불가능.
- 해당 로직 실행 전까지 작동여부 확인이 불가
- 실행시점에 오류가 발견됨
QueryDSL
- 문자가 아닌 코드로 작성
- 컴파일 시점 문법 오류 발견이 가능
- 코드 자동 완성
- 동적쿼리 가능
- JPQL 단점 보완
[gradle 설정]
gradle 설정은 gradle 버전마다 상이하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
buildscript {
ext {
springBootVersion = '2.1.4.RELEASE'
querydslPluginVersion = '1.0.10'
}
repositories {
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" } // plugin 저장소
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "io.spring.gradle:dependency-management-plugin:1.0.7.RELEASE"
classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:${querydslPluginVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: "com.ewerk.gradle.plugins.querydsl"
apply plugin: 'eclipse'
group = 'com.jpp'
version = '0.0.1'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
compile 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
compile 'org.springframework.boot:spring-boot-starter-tomcat'
testCompile('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compile 'org.apache.tomcat.embed:tomcat-embed-jasper'
compile 'javax.servlet:jstl'
compile 'org.json:json:20180813'
compile 'com.google.code.gson:gson:2.8.5'
compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.2'
compile group: 'org.aspectj', name: 'aspectjrt', version: '1.9.2'
compile 'com.querydsl:querydsl-jpa' // querydsl
compile 'com.querydsl:querydsl-apt' // querydsl
}
test {
useJUnitPlatform()
ignoreFailures = true
}
def querydslSrcDir = 'src/main/generated'
querydsl {
library = "com.querydsl:querydsl-apt"
jpa = true
querydslSourcesDir = querydslSrcDir
}
sourceSets {
main {
java {
srcDirs = ['src/main/java', querydslSrcDir]
}
}
}
compileQuerydsl{
options.annotationProcessorPath = configurations.querydsl
}
configurations {
querydsl.extendsFrom compileClasspath
}
|
cs |
gradle build 후 지정한 경로(src/main/generated)에 Query Class가 생성되었음을 확인 할 수 있다.
[QueryDSL 사용]
1
2
3
4
5
6
7
8
9
|
@PersistenceContext
EntityManager em;
public List<User> selectUserByNm(String nm){
JPAQueryFactory jqf = new JPAQueryFactory(em);
return jqf.selectFrom(user).where(user.name.eq(nm)).fetch();
}
|
cs |
참고 :
Tacademy 김영한 개발자님의 강의
김영한 개발자님의 JPA 저서
https://www.baeldung.com/spring-data-jpa-query
https://www.baeldung.com/querydsl-with-jpa-tutorial
'back > JPA' 카테고리의 다른 글
[JPA] cascade (0) | 2022.11.10 |
---|---|
[JPA] equals , hashcode (0) | 2022.11.08 |
[JPA] JPA 영속성 컨텍스트 (0) | 2020.03.08 |
[JPA] 연관관계 매핑 : 단방향, 양방향 매핑 (0) | 2020.03.01 |
[JPA] JPA 기초 설정 및 entity 필드 매핑 (0) | 2020.02.27 |