JPA的好搭档 - QueryDSL(jpa缺点)
ccwgpt 2024-09-21 13:43 32 浏览 0 评论
今天给大家介绍一个JPA的好搭档:QueryDSL。
0. 前言
相对于 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);
看着想吐,就是直接写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-jpa'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
引入JPAQueryFactory
@Service
public class DemoQueryDSL {
@Autowired
private JPAQueryFactory queryFactory;
}
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;//部门名称
}
编译后,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();
}
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();//返回多个结果时,只取第一个
}
小结
以上就是 QueryDSL 的简单应用,用写SQL的方法来写代码,是不是很舒服呢!文中的例子仅仅浅尝辄止,希望大家可以实际应用一下,后续我也会更深入的讲解一些 QueryDSL 的高级用法。
相关推荐
- 团队管理“布阵术”:3招让你的团队战斗力爆表!
-
为何古代军队能够以一当十?为何现代企业有的团队高效似“特种部队”,有的却松散若“游击队”?**答案正隐匿于“布阵术”之中!**今时今日,让我们从古代兵法里萃取3个核心要义,助您塑造一支战斗力爆棚的...
- 知情人士回应字节大模型团队架构调整
-
【知情人士回应字节大模型团队架构调整】财联社2月21日电,针对原谷歌DeepMind副总裁吴永辉加入字节跳动后引发的团队调整问题,知情人士回应称:吴永辉博士主要负责AI基础研究探索工作,偏基础研究;A...
- 豆包大模型团队开源RLHF框架,训练吞吐量最高提升20倍
-
强化学习(RL)对大模型复杂推理能力提升有关键作用,但其复杂的计算流程对训练和部署也带来了巨大挑战。近日,字节跳动豆包大模型团队与香港大学联合提出HybridFlow。这是一个灵活高效的RL/RL...
- 创业团队如何设计股权架构及分配(创业团队如何设计股权架构及分配方案)
-
创业团队的股权架构设计,决定了公司在随后发展中呈现出的股权布局。如果最初的股权架构就存在先天不足,公司就很难顺利、稳定地成长起来。因此,创业之初,对股权设计应慎之又慎,避免留下巨大隐患和风险。两个人如...
- 消息称吴永辉入职后引发字节大模型团队架构大调整
-
2月21日,有消息称前谷歌大佬吴永辉加入字节跳动,并担任大模型团队Seed基础研究负责人后,引发了字节跳动大模型团队架构大调整。多名原本向朱文佳汇报的算法和技术负责人开始转向吴永辉汇报。简单来说,就是...
- 31页组织效能提升模型,经营管理团队搭建框架与权责定位
-
分享职场干货,提升能力!为职场精英打造个人知识体系,升职加薪!31页组织效能提升模型如何拿到分享的源文件:请您关注本头条号,然后私信本头条号“文米”2个字,按照操作流程,专人负责发送源文件给您。...
- 异形柱结构(异形柱结构技术规程)
-
下列关于混凝土异形柱结构设计的说法,其中何项正确?(A)混凝土异形柱框架结构可用于所有非抗震和抗震设防地区的一般居住建筑。(B)抗震设防烈度为6度时,对标准设防类(丙类)采用异形柱结构的建筑可不进行地...
- 职场干货:金字塔原理(金字塔原理实战篇)
-
金字塔原理的适用范围:金字塔原理适用于所有需要构建清晰逻辑框架的文章。第一篇:表达的逻辑。如何利用金字塔原理构建基本的金字塔结构受众(包括读者、听众、观众或学员)最容易理解的顺序:先了解主要的、抽象的...
- 底部剪力法(底部剪力法的基本原理)
-
某四层钢筋混凝土框架结构,计算简图如图1所示。抗震设防类别为丙类,抗震设防烈度为8度(0.2g),Ⅱ类场地,设计地震分组为第一组,第一自振周期T1=0.55s。一至四层的楼层侧向刚度依次为:K1=1...
- 结构等效重力荷载代表值(等效重力荷载系数)
-
某五层钢筋混凝土框架结构办公楼,房屋高度25.45m。抗震设防烈度8度,设防类别丙类,设计基本地震加速度0.2g,设计地震分组第二组,场地类别为Ⅱ类,混凝土强度等级C30。该结构平面和竖向均规则。假定...
- 体系结构已成昭告后世善莫大焉(体系构架是什么意思)
-
实践先行也理论已初步完成框架结构留余后人后世子孙俗话说前人栽树后人乘凉在夏商周大明大清民国共和前人栽树下吾之辈已完成结构体系又俗话说青出于蓝而胜于蓝各个时期任务不同吾辈探索框架结构体系经历有限肯定发展...
- 框架柱抗震构造要求(框架柱抗震设计)
-
某现浇钢筋混凝土框架-剪力墙结构高层办公楼,抗震设防烈度为8度(0.2g),场地类别为Ⅱ类,抗震等级:框架二级,剪力墙一级,混凝土强度等级:框架柱及剪力墙C50,框架梁及楼板C35,纵向钢筋及箍筋均采...
- 梁的刚度、挠度控制(钢梁挠度过大会引起什么原因)
-
某办公楼为现浇钢筋混凝土框架结构,r0=1.0,混凝土强度等级C35,纵向钢筋采用HRB400,箍筋采用HPB300。其二层(中间楼层)的局部平面图和次梁L-1的计算简图如图1~3(Z)所示,其中,K...
- 死要面子!有钱做大玻璃窗,却没有钱做“柱和梁”,不怕房塌吗?
-
活久见,有钱做2层落地大玻璃窗,却没有钱做“柱子和圈梁”,这样的农村自建房,安全吗?最近刷到个魔幻施工现场,如下图,这栋5开间的农村自建房,居然做了2个全景落地窗仔细观察,这2个落地窗还是飘窗,为了追...
- 不是承重墙,物业也不让拆?话说装修就一定要拆墙才行么
-
最近发现好多朋友装修时总想拆墙“爆改”空间,别以为只要避开承重墙就能随便砸!我家楼上邻居去年装修,拆了阳台矮墙想扩客厅,结果物业直接上门叫停。后来才知道,这种配重墙拆了会让阳台承重失衡,整栋楼都可能变...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- bootstrap框架 (43)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- laravel框架 (46)
- express框架 (43)
- scrapy框架 (52)
- beego框架 (42)
- java框架spring (43)
- grpc框架 (55)
- 前端框架bootstrap (42)
- orm框架有哪些 (43)
- ppt框架 (48)
- 内联框架 (52)
- winform框架 (46)
- gui框架 (44)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)