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

+ Recent posts