时间戳
时间戳
首页
站长
网站Gzip压缩检测
网站死链检测
Whois查询工具
ICP网站备案查询
Meta标签优化分析
网页关键词密度检测
HTTP状态码查询
微信域名检测工具
htaccess转nginx
生成网页Meta标签
生成桌面快捷方式
rem与px转换工具
在线制作ico图标
在线图片免费压缩
在线定时刷新网址
在线调色板
RGB颜色查询
代码对比/归并
JSON工具
Json格式化
Json格式化(上下)
Json格式化(左右)
Json在线压缩转义
Json生成C#实体类
Json生成Java实体类
Json生成Go结构体
SQL转Java实体类
XML和Json在线互转
Excel/CSV转Json格式
Json转Excel/CSV格式
JSON和GET参数互转
JSON转YAML
格式化转换
HTML格式化/压缩
CSS格式化/压缩
JS格式化/压缩
JS加密/解密
JS代码混合加密
SQL压缩/格式化
PHP代码格式化工具
XML压缩/格式化
Html/JS互转
Html转义工具
Html转C#/JSP
Html转PHP代码
Html转ASP/Perl
Excel转HTML表格
Html表格生成器
HTML/MarkDown互转
正则表达式测试工具
正则生成代码
Html过滤工具
运行Js/html/css
Xpath工具
加解密编码
MD5加密工具
URL网址16进制加密
迅雷旋风URL加解密
Base64加密/解密
Escape加密/解密
对称加密/解密
SHA/SHA256加密
散列/哈希加密大全
摩尔斯电码加解密
密码生成器
UUID在线生成
GUID在线生成
条形码生成器
IP/数字地址转换
图片转Base64
UTF-8转GBK
Unicode/ASCII转换
ASCII编码/解码
URL编码/解码
KeyCode键盘按键码
Android按键码
键盘测试工具
网络
IP地址归属地查询
Websocket测试
获取浏览器信息
公共DNS
各地区公共DNS
文本数字
Html在线编辑器
文章自动排版
文章内容采集
简繁字体转换
汉字转为拼音
火星文转换器
文本内容替换
文本内容对比
在线统计字数工具
内容去重工具
文字特效工具
字符串文本压缩工具
驼峰与下划线互转
全角半角转换
英文字母大小写转换
人民币大写转换工具
随机数生成器
Unix时间戳在线转换
常用进制转换工具
RGB颜色在线转换
计算
利率计算器在线
子网掩码计算器
在线科学计算器
对照列表
常用User-Agent
Content-Type对照表
Request请求大全
HTTP请求头大全
HTTP状态码
ASCII对照表
HTML特殊字符转义
常见端口大全
Bootstrap字体图标
Android Manifest权限大全
Linux常用命令大全
其他
在线涂鸦画板
在线时钟
世界各地时间
世界各国首都查询
世界各地货币查询
世界各国区号时差查询
世界节日查询
全国少数民族分布查询
中国历史朝代时间查询表
特殊符号大全
历史上的今天
方案
文章
首页
>
技术文章
> JPQ整合Querydsl入门篇
JPQ整合Querydsl入门篇
askajohnny
2019-12-24 10:18
原文
# JPQ整合Querydsl入门篇 不知道你们喜不喜欢用JPA ,我本人是很喜欢 不要和我说JPA不适合复杂查询等等的,你要知道现在都是微服务,只要你服务器拆分够细表设计够合理,都是服务之间调能用到多少关联查询呢? 而且结合了QueryDsl工具让你写起来更快,本博客后台就是使用了JPA+QueryDsl 做的查询 下面开始讲解吧。 ### 1.为什么要用QueryDsl 先来看个代码 @Override public List
findByPcardCardOrder( PcardCardOrder pcardCardOrder,String applyInstName2,Integer page, Integer rows) { StringBuffer sql = new StringBuffer( "SELECT p.*" +",p2.vcard_make_des" +",p3.cardnum_rule_id,p3.vtype_nm" +",p4.cn_card_bin,p4.cn_nm" +",p5.inst_id,p5.inst_name,p5.apply_range,p5.card_name,p5.card_type,p5.bin_card_material" +",p6.inst_name AS apply_inst_name " +",p7.inst_name AS apply_inst_name2" + ",p8.inst_name as receive_inst_name" + " FROM " +" tbl_pcard_card_order p LEFT JOIN tbl_pcard_vcard_make p2 ON p.make_id = p2.vcard_make_id" +" LEFT JOIN tbl_pcard_vtype p3 ON p2.vcard_make_vtype_id=p3.vtype_id" +" LEFT JOIN tbl_pcard_cardnum_rule p4 ON p3.cardnum_rule_id=p4.cn_id" +" LEFT JOIN tbl_pcard_cardbin p5 ON p4.cn_card_bin=p5.card_bin" +" LEFT JOIN tbl_pcard_institution p6 ON p5.apply_range=p6.inst_id" +" LEFT JOIN tbl_pcard_institution p7 ON p.apply_inst_id=p7.inst_id" +" LEFT JOIN tbl_pcard_institution p8 ON p.receive_inst=p8.inst_id" +" WHERE 1=1 "); int i = 1; Map
map = new HashMap
(); if (!StringUtils.isEmpty(pcardCardOrder.getCordId())) { sql.append(" and p.cord_id="); sql.append("?" + i); map.put(i + "", pcardCardOrder.getCordId()); i++; } if (!StringUtils.isEmpty(pcardCardOrder.getAppointMchtcard())) { sql.append(" and p.appoint_mchtcard="); sql.append("?" + i); map.put(i + "", pcardCardOrder.getAppointMchtcard()); i++; } if (!StringUtils.isEmpty(pcardCardOrder.getMakeId())) { sql.append(" and p.make_id like "); sql.append("?" + i); map.put(i + "","%%"+ pcardCardOrder.getMakeId()+"%%"); i++; } if (!StringUtils.isEmpty(applyInstName2)) { sql.append(" and p7.inst_name like "); sql.append("?"+i); map.put(i+"","%%"+applyInstName2+"%%"); i++; } sql.append(" order by p.ct_dm desc"); Query query = entityManager.createNativeQuery(sql.toString()); for (String key : map.keySet()) { query.setParameter(key, map.get(key)); } if (page != null && rows != null) { query.setFirstResult(rows * (page - 1)); query.setMaxResults(rows); } return query.getResultList(); } 多的不用说了吧,我看到这种代码就想吐 也没心情看,说真的这个还算好的了,还见过更多更恶心的 ### 2.了解QueryDsl [QueryDsl官网文档](http://www.querydsl.com/static/querydsl/4.1.3/reference/html_single/) QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。 Querydsl可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。 借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Mongodb 等等。。。 ### 3.引入QueryDsl #### 3.1 pom中引入依赖
com.querydsl
querydsl-jpa
com.querydsl
querydsl-apt
provided
#### 3.2 添加maven插件 添加这个插件是为了让程序自动生成query type(查询实体,命名方式为:"Q"+对应实体名)。 注:在使用过程中,如果遇到query type无法自动生成的情况,用maven更新一下项目即可解决(右键项目->Maven->Update Project), 或者之间终端输入 mvn clean compile 编译一下就会自动生成Q 类
com.mysema.maven
apt-maven-plugin
1.1.3
process
target/generated-sources/java
com.querydsl.apt.jpa.JPAAnnotationProcessor
#### 3.3 JPA的基本配置,在application.yml中配置 spring: jpa: database: mysql show-sql: true open-in-view: true hibernate: ddl-auto: update naming: strategy: org.hibernate.cfg.DefaultComponentSafeNamingStrategy properties: hibernate: dialect: org.hibernate.dialect.MySQL5InnoDBDialect format_sql: true #### 3.4 创建实体 这里只是列出了部分属性 @Data @Entity @EntityListeners(AuditingEntityListener.class) public class BlogInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** * 博客标题 */ private String blogTitle; /** * 博客内容 */ @Column(columnDefinition = "text") private String blogContent; /** * 博客简要 */ private String blogShortContent; } #### 3.5 引入JPAQueryFactory @Service public class BlogInfoServiceImpl implements BlogInfoService { private JPAQueryFactory queryFactory; @PostConstruct //指定初始化queryFactory public void init() { queryFactory = new JPAQueryFactory(entityManager); } @PersistenceContext private EntityManager entityManager; } ### 4.使用QueryDsl 先定义一个Q类 ,Q类是QueryDsl帮我们编译的时候生成的对应的是实体类 QBlogInfo qBlogInfo = QBlogInfo.blogInfo; ### 5. 查询所有属性 通过queryFactory查询 queryFactory.select(qBlogInfo) .from(qBlogInfo) 表示查询BlogInfo所有的属性 相当于select * from blog_Info ### 6.查询特定属性 queryFactory.select(qBlogInfo.blogTitle,qBlogInfo.blogContent) .from(qBlogInfo) 表示查询BlogInfo实体的 blogTitle 属性 相当于 select blogTitle,blogContent from blog_Info ### 7.带where查询 queryFactory.select(qBlogInfo) .from(qBlogInfo) .where(qBlogInfo.id.eq(1)) 相当于 select blogTitle from blog_Info where id = 1; ### 8.多表查询 多表返回Tuple ,tuple.get(0) 就是第一个属性qBlogInfo , tuple.get(1) 就是获取第二个属性 typeName queryFactory.select(qBlogInfo, qBlogType.typeName) .from(qBlogInfo) .leftJoin(qBlogType) .on(qBlogInfo.blogTypeId.eq(qBlogType.id)) ### 9.排序查询 追加orderBy方法指定按照什么属性进行排序 queryFactory.select(qBlogInfo) .from(qBlogInfo) .orderBy(qBlogInfo.createTime.desc()) ### 10.分页查询 追加offset 偏移位置,就是从哪条数据开始查询 最佳limit 限制查询多少条 JPAQuery jpaQuery = queryFactory.select(qBlogInfo, qBlogType.typeName) .from(qBlogInfo) .leftJoin(qBlogType) .on(qBlogInfo.blogTypeId.eq(qBlogType.id)) .orderBy(qBlogInfo.createTime.desc()) .offset(pageable.getPageNumber() * pageable.getPageSize()) .limit(pageable.getPageSize()); ### 11.执行查询 通过上面构造的 jpaQuery jpaQuery.fetchResults(); 查询list ,返回 list 泛型根据是否有多表查询, 如果没有就返回 比如上面的QBlogInfo 对应的 BlogInfo ==》 list
, 如果有多表查询 返回 list
类型,再根据tuple.get(0) tuple.get(1) 去获取对应的属性 jpqQuery.fetchOne(); 查询单条记录 比如where id = xxx 的时候可以使用 ### 12.样例 根据ID查询博客 /** * 根据 Id 查询博客信息 * * @param id : id * @return : 博客信息 */ @Override public BlogInfoVo queryById(Long id) { QBlogInfo qBlogInfo = QBlogInfo.blogInfo; QBlogType qBlogType = QBlogType.blogType; Tuple tuple = queryFactory.select(qBlogInfo, qBlogType.typeName) .from(qBlogInfo) .leftJoin(qBlogType) .on(qBlogInfo.blogTypeId.eq(qBlogType.id)) .where(qBlogInfo.id.eq(id)) .fetchOne(); BlogInfo blogInfo = tuple.get(0, BlogInfo.class); Gson gson = new Gson(); List
list = gson.fromJson(blogInfo.getAnchorJson(), List.class); BlogInfoVo blogInfoVo = BlogInfoConverter.INSTANCE.domain2vo(tuple.get(0, BlogInfo.class)).setBlogTypeName(tuple.get(1, String.class)); blogInfoVo.setAnchors(list); return blogInfoVo; } ### 总结: 本篇简单介绍了在JPA中如何使用QueryDsl,包括pom依赖 插件, queryFactory的初始化,以及 各种例子包括 分页 排序 等等查询 看着使用QueryDsl写出来的sql查询 是不是很舒服呢! 后续会深入讲解一下 QueryDsl的高级点的用法 > 个人博客地址: https://www.askajohnny.com 欢迎访问! > 本文由博客一文多发平台 [OpenWrite](https://openwrite.cn?from=article_bottom) 发布!
1
2
推荐阅读
css3渐变
常用快捷键(转)
Toad&PL/SQL修改查询信息
VSS Admin密码清除方法
C# 连接数据库
alias(让liunx 更方便使用)
文件处理
mysql基础sql语法联系
zip矩阵转至
scrapy(2)