# QueryDSL
1,QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。
2,Querydsl可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。
3,借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
# Querydsl for JPA
使用
类型安全
的方式书写原生JPQL
。
Querydsl for JPA
是JPQL
(类SQL语法,类型不安全) 和Criteria
(复杂度偏高,学习曲线较陡峭) 查询的替代方案
# Querydsl for SQL
使用
类型安全
的方式书写原生SQL
。
和JPA方式的比较(Native表示原生SQL)
- Native不需要JPA对象,JPA需要。
- Native需要直连数据库生成Q对象(可自定义前缀,一般定义为N),JPA需要读取JPA对象生成Q对象(不可自定义前缀)
- Native的灵活性比JPA高,可以出色解决JPA中对子查询嵌套等的短板,通常原生SQL能实现的,Native也能实现
- JPA的易操作性比Native要好,可全面使用JPA对象的各种特性
- Native方式的执行过程:java对象 > 解析成sql语句 > 提交给数据库
- JPA方式的执行过程:java对象 > 解析成JPQL语句(如果用的是Hibernate,则解析成HQL语句) > 解析成sql语句 > 提交给数据库
- JPA 和 Native均支持不同数据库方言,并可自动转换语法,可以在数据库中无缝切换(如果在使用Native时,自定义了
template
表达式,并使用了数据库特性的函数方法时,可能导致不同数据库之间无法平滑切换)
综上:优先使用JPA方式,当JPA无法满足生产需求时,才考虑使用Native方式
集成方式
I. 导入依赖包和插件
<!-- Querydsl for SQL的依赖包 -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql-codegen</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<!-- Querydsl for SQL的插件 -->
<plugin>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>${querydsl.version}</version>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
<configuration>
<namePrefix>N</namePrefix>
<sourceFolder></sourceFolder>
<!-- 只需要写需要生成的表名,按英文逗号分隔,表名支持LIKE语法方式进行命名 -->
<tableNamePattern>electrode_%,sys_file</tableNamePattern>
<!-- 数据库连接信息,改成你自己的 -->
<jdbcDriver>com.mysql.cj.jdbc.Driver</jdbcDriver>
<jdbcUrl>jdbc:mysql://192.168.1.55:3306/kg_industry_gxjgzx</jdbcUrl>
<jdbcUser>kg_industry_gxjgzx</jdbcUser>
<jdbcPassword>kg_industry_gxjgzx</jdbcPassword>
<!-- 不建议改 -->
<packageName>com.jfbrother.nativesql.domain</packageName>
<targetFolder>target/generated-sources/java</targetFolder>
</configuration>
<dependencies>
<!-- 上方使用哪种数据库,这里就需要添加对应的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
</dependencies>
</plugin>
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
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
II. 在启动类构造
SQLQueryFactory
的Bean
@Bean
public SQLQueryFactory sqlQueryFactory(@Qualifier("primaryDataSource") DataSource dataSource){
SQLTemplates templates = new MySQLTemplates();
return new SQLQueryFactory(new com.querydsl.sql.Configuration(templates), dataSource);
}
1
2
3
4
5
2
3
4
5
III. 在service中注入
SQLQueryFactory
@Autowired
private SQLQueryFactory sqlQueryFactory;
1
2
2
Ⅳ. 含有子查询的例子,无子查询写法和JPA类似,但是建议直接使用JPA模式,不要采用该原生SQL模式
NElectrodeProceSpecs nElectrodeProceSpecs = NElectrodeProceSpecs.electrodeProceSpecs;
NElectrodeProceSplit nElectrodeProceSplit = NElectrodeProceSplit.electrodeProceSplit;
SubQueryExpression subQuery1 = SQLExpressions.select(Expressions.stringPath("id")).from(nElectrodeProceSpecs).groupBy(nElectrodeProceSpecs.id).where(nElectrodeProceSpecs.createTime.gt(1));
SubQueryExpression subQuery2 = SQLExpressions.select(nElectrodeProceSplit.id, nElectrodeProceSplit.electrodeProceSpecsId).from(nElectrodeProceSplit);
List<Tuple> fetch = sqlQueryFactory.select(Expressions.template(String.class, "ss.electrode_proce_specs_id"),
Expressions.template(String.class, "ss.id"))
.from(subQuery1, Expressions.stringPath("dd"))
.leftJoin(subQuery2, Expressions.stringPath("ss"))
.on(Expressions.template(String.class, "dd.id").eq(
Expressions.template(String.class, "ss.electrode_proce_specs_id")
))
.limit(10)
.fetch();
if (fetch.size() > 0) {
log.debug(fetch.get(0).get(Expressions.template(String.class, "ss.electrode_proce_specs_id")));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
← ELK 集成