JPA的好搭档 - QueryDSL
时间:2025-11-05 12:05:34 出处:人工智能阅读(143)
相对于 MyBatis ,的档本人更喜欢 Spring Data JPA ,好搭因为它更符合面向对象的的档思想,然而 JPA 对复杂的好搭查询支持较弱,常见的的档有两种方式:
一种方式是Repository继承JpaSpecificationExecutor接口,优点是好搭支持复杂查询、编译期可以规避一些语法错误,的档缺点是好搭语法晦涩难懂,学习成本太高。的档

还有一种方式就是好搭直接写 SQL ,可以通过JdbcTemplate或者@Query注解的的档方式查询,优点是好搭简单,缺点嘛...先看段代码:
复制@Query(value="select bs.* from " + "(select t.baseid,的档t.basesn,t.basecreatorfullname,t.basestatus,t.basesummary,北京 faultprovince, 北京 faultcity, " + "replace(t.INC_ResponseLevel,响应,) inc_responselevel,t.inc_happentime,t.basecreatedate,t.inc_equipmentmanufacturer, " + "t.inc_ne_name,t.inc_alarm_id,t.site_alerttype,t.alarmlevel,t.inc_alarm_desc,t.baseacceptouttime,t.basedealouttime, " + "decode(t.flagPretreatment,null,否,未预处理,否,是) flagpretreatment,decode(t.flagPretreatment,null,否,未预处理,否,是) flagpretreatment2, " + "decode(nvl(t.isImportantIncident, 0),1,是,否) isimportantincident, decode(nvl(t.INC_IsEffectOP, 0),1,是,否) inc_iseffectop, " + "t.operationdeal, t.t0_deal,t.faultdescription,t.dealguomodo,t.inc_alarm_cleartime,t.clearinctime, " + "t.renewtime,t.baseclosedate,nvl2(t.checkdealresult,是,否) checkdealresult,g.jtitem1,g.jtitem2,g.jtitem3,t.reasontype " + "from T_DEMO t, T_DEMO_MAP g " + "where t.Sheet_type = 传输网络故障处理工单 and t.basestatus = 已归档 " + "and t.baseCloseDate >= :beginTime and t.baseCloseDate < :endTime " + "and (t.Withdraw_Desc = g.withdraw_desc or t.alarmname = g.alarmname) " + "union all " + "select t.baseid,t.basesn,t.basecreatorfullname,t.basestatus,t.basesummary,北京 faultprovince, 北京 faultcity, " + "replace(t.INC_ResponseLevel,响应,) inc_responselevel,t.inc_happentime,t.basecreatedate,t.inc_equipmentmanufacturer, " + "t.inc_ne_name,t.inc_alarm_id,t.site_alerttype,t.alarmlevel,t.inc_alarm_desc,t.baseacceptouttime,t.basedealouttime, " + "decode(t.flagPretreatment,null,否,未预处理,否,是企商汇) flagpretreatment,decode(t.flagPretreatment,null,否,未预处理,否,是) flagpretreatment2, " + "decode(nvl(t.isImportantIncident, 0),1,是,否) isimportantincident, decode(nvl(t.INC_IsEffectOP, 0),1,是,否) inc_iseffectop, " + "t.operationdeal,t.t0_deal,t.faultdescription,t.dealguomodo,t.inc_alarm_cleartime,t.clearinctime, " + "t.renewtime,t.baseclosedate,nvl2(t.checkdealresult,是,否) checkdealresult,w.jtitem1,w.jtitem2,w.jtitem3,t.reasontype " + "from WF_BMCC_EOMS_ITDealFault t, (select distinct c.value,c.jtitem1,c.jtitem2,c.jtitem3 from WF_Config_EL_00_NetType c) w " + "where (t.Sheet_type = test0 or t.Sheet_type = test1 or t.Sheet_type = test2 " + "or t.Sheet_type = test3 or t.Sheet_type = test4) and t.basestatus = 已归档 " + "and t.baseCloseDate >= :beginTime and t.baseCloseDate < :endTime " + "and t.faultclass = w.value "+ " ) bs " + "where not exists (select dp.processbaseid from T_DEAL dp,T_GROUPS dg where dp.ProcessBaseSchema = " + "DEALFAULT and dp.processbaseid = bs.baseid and dp.groupid = dg.groupid) ", nativeQuery=true) List<DemoEntity> findOne(@Param("beginTime") long beginTime, @Param("endTime") long endTime);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.看着想吐,就是好搭直接写SQL的缺点。
下面隆重介绍 JPA 的的档最佳搭档:QueryDSL。它的语法跟SQL一样简单,且代码清晰,具有代码提示、编译期错误检查等优势。同时,在架构的层次上实现了读写分离:JPA负责增删改、QueryDSL负责查询。
1. QueryDsl介绍QueryDSL 是一个通用的查询框架,专注于通过 Java API 构建类型安全的SQL查询。
QueryDSL 可以通过一组通用的查询 API 为用户构建出适合不同类型ORM框架或者是 SQL 的查询语句,也就是说 QueryDSL 是基于各种 ORM 框架以及 SQL 之上的一个通用的网站模板查询框架。
借助 QueryDSL 可以在任何支持的 ORM 框架或者 SQL 平台上以一种通用的API方式来构建查询。目前 QueryDSL 支持的平台包括 JPA、JDO、SQL、Mongodb 等等。
2. 引入QueryDSL本文以gradle构建为例,前提是已引入 Spring Data Jpa ,且JPA可正常使用。
复制implementation com.querydsl:querydsl-jpaannotationProcessor com.querydsl:querydsl-apt:5.0.0:jpaannotationProcessor jakarta.persistence:jakarta.persistence-api1.2.3.引入JPAQueryFactory
复制@Service
public class DemoQueryDSL {@Autowired
private JPAQueryFactory queryFactory;}1.2.3.4.5. 3. 创建JPA Entity我们分别创建两个示例实体类:职员表、部门表。
复制/** * 职员表 */@Data
@Entity
@Table(name = "T_EMP")public class Emp {@Id
private String id;//ID
@Column
private String name;//姓名
@Column
private Integer age;//年龄
@Column
private String sex;//性别
@Column
private String depId;//部门ID
}/** * 部门表 */@Data
@Entity
@Table(name = "T_DEP")public class Dep {@Id
private String id;//ID
@Column
private String depName;//部门名称
}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.编译后,QueryDSL 会帮助我们会自动生成两个Q类:QEmp、QDep ,我们之后进行的所有查询都是围绕这些Q类来进行的。
4. 简单查询QueryDSL提供了一种类似于SQL的面向对象写法,并且是类型安全的,搭配上IDEA的语句提示功能,写起SQL来非常舒服。
请欣赏下面的例子:
复制public void simpleSql(){ QEmp emp = QEmp.emp;//员工表
/** * 简单条件查询、排序,源码下载相当于sql: * select * from T_EMP * where name like 张% and age > 25 * order by age desc; */ List<Emp> empList = queryFactory.select(emp) .where(emp.name.startsWith("张").and(emp.age.gt(25))) .orderBy(emp.age.desc()) .fetch(); /** * 分组查询,相当于sql: * select e.dep_id, max(e.age) from T_EMP e * grouping by e.depId; */ List<Tuple> list = queryFactory.select(emp.depId, emp.age.max()) .groupBy(emp.depId) .fetch(); /** * 分页查询,相当于sql: * select * from T_EMP e * where e.dep_id=123 * limit 20 10; */ List<Emp> pageList = queryFactory.select(emp) .where(emp.depId.eq("123")) .offset(20) .limit(10) .fetch();}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. 5. 复杂查询QueryDSL对于复杂查询的支持也是相当优秀的,比如多表关联、动态条件查询等。
复制public void complexSql(){ QEmp emp = QEmp.emp;//员工表
QDep dep = QDep.dep;//部门表
/** * 关联查询,相当于sql: * select e.* from T_EMP e * left join T_DEP d on e.dep_id = d.id * where d.dep_name = 财务部 */ List<Emp> empList = queryFactory.select(emp) .from(emp) .leftJoin(dep).on(emp.depId.eq(dep.id)) .where(dep.depName.eq("财务部")) .fetch(); /** * 嵌套查询,相当于sql: * select e.* from T_EMP e * where e.dep_id = ( * select id form T_DEP where dep_name = 财务部 * ) */ List<Emp> empList1 = queryFactory.select(emp) .from(emp) .where(emp.depId.eq( queryFactory.select(dep.id).from(dep) .where(dep.depName.eq("财务部")) )) .fetch(); /** * 动态条件、别名、获取不同结果: */ BooleanBuilder condition = new BooleanBuilder(); condition.and(emp.age.goe(25)); if (true) {//动态条件
condition.and(emp.sex.eq("男"));} queryFactory.select(emp.name.as("fullname")) .where(condition) .fetch();//查找多个结果,返回集合
//.fetchOne();//查询只返回一个结果,如果返回多个则抛异常
//.fetchFirst();//返回多个结果时,只取第一个
}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. 小结以上就是 QueryDSL 的简单应用,用写SQL的方法来写代码,是不是很舒服呢!文中的例子仅仅浅尝辄止,希望大家可以实际应用一下,后续我也会更深入的讲解一些 QueryDSL 的高级用法。
猜你喜欢
- 微星1022的特点及性能评测(一款令人心动的高性能笔记本电脑)
- 台式电脑装系统教程——WindowsXP(详细步骤图文教程,轻松完成安装)
- 映泰8100官方教程(全面解析映泰8100官方教程,助您成为游戏高手)
- ThinkPadX230(轻薄便携,高性能续航,完美助力办公)
- R9M385显卡的性能评测及优势分析(解析R9M385显卡的关键特性,为你带来无与伦比的游戏体验)
- U盘安装Windows10(使用U盘轻松安装Windows10,无需光盘)
- 华为P8青春版与荣耀手环的完美搭配(领略智能生活新体验,华为P8青春版与荣耀手环的强强联合)
- 苹果U盘双系统教程(轻松学会使用苹果U盘创建双系统)
- 百发100怎么样?(探索百发100对于个人成长的影响)