关于 QueryDSL
最近写项目,使用到了 Jpa 这个 ORM 规范支持,使用注解的方式实现 Sql ,但是用过 Jpa 的同学都知道 Jpa 对于单表操作很灵活,但是对于复杂一些的 SQL 就是很不友好了,所以这个地方我们就用到了 QueryDSL 来实现复杂的 Sql(另外强行安利一波 Tk-MyBatis)
什么是 QueryDSL ?
QueryDSL仅仅是一个通用的查询框架,专注于通过 JavaAPI 构建类型安全的 Sql 查询,也可以说 QueryDSL 是基于各种 ORM 框架以及 Sql 之上的一个通用的查询框架,QueryDSL 的查询,类是于 SQL 查询,很全面只不过一个是用 SQL 一个是用代码来代替 SQL -- 不多了解 QueryDSL 的其他方面了,直接进入看配置和代码吧,毕竟博主也是刚刚接触这个查询框架,就不做过多的误导了
说一下,下面示例的环境 -- MyBatis + IDEA + JPA + QueryDSL
---------------------------------------------------- 手动分界线 ----------------------------------------------------
以下为项目操作(创建项目的操作就先省略掉了,这个应该都会,不会的可以去看博主的其他博客):
首先配置 pom.xml 更古不变的定律 T_T!! 对了在安利一个插件 lombok,配合 QueryDSL 可能会更好
<!--?QueryDSL?相关依赖?--><dependency>????<groupId>com.querydsl</groupId>????<artifactId>querydsl-jpa</artifactId></dependency><dependency>????<groupId>com.querydsl</groupId>????<artifactId>querydsl-apt</artifactId>????<scope>provided</scope></dependency><!--?lombok?相关依赖?--><dependency>????<groupId>org.projectlombok</groupId>????<artifactId>lombok</artifactId>????<version>1.16.10</version>????<scope>provided</scope></dependency>Ps:lombok 可以已注解的方式来对代码进行简化,省去了 get 和 set 方法,至于怎么使用 lombok ,先看本文示例吧
配置 application.properties 文件
server.port=8080server.servlet.context-path=/server.tomcat.uri-encoding=utf-8###添加?MySQL?数据库配置spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boot_test?serverTimezone=UTC&characterEncoding=UTF-8&useUnicode=true###用户名spring.datasource.username=xxx###密码spring.datasource.password=xxx###驱动spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver#是否自动生/更新成表,根据什么策略spring.jpa.hibernate.ddl-auto=update#JPA配置spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialectspring.jpa.properties.hibernate.legacy_limit_handler=true#是否展示sqlspring.jpa.show-sql=?true创建 entiy 层,因为要先创建完实体类才可以去生成 QueryDSL
package?com.cs.querydsl.model;import?lombok.Data;import?org.hibernate.annotations.GenericGenerator;import?javax.persistence.*;/**?*?@ClassName:User?*?@Description:TODO?User?实体类?*?@Author?LinLuoChen?*?@Date?2019/7/10/14:02?*?@Version?V1.0?**/@Data?//?lombok?工具省去了?GET?SET?方法@Entity?//?声明这个是一个实体类@Table(name="user")?//?对应的数据库的那个表public?class?User?{????/**?????*?@Description?ID?????*?@Author?LinLuoChen?????*?@Date??10:44?????**/????@Id????@GenericGenerator(name="id",?strategy="uuid")?//?这里我们的?ID?用的是?UUID????@GeneratedValue(generator="id")????private?Integer?id;????/**?????*?@Description?姓名?????*?@Author?LinLuoChen?????*?@Date??10:44?????**/????@Column(name?=?"name")????private?String?name;????/**?????*?@Description?密码?????*?@Author?LinLuoChen?????*?@Date??10:44?????**/????@Column(name?=?"password")????private?String?password;}开始编写 Dao 层,引入JPA 的接口 -- !!重要 !!!
package?com.cs.querydsl.dao;import?com.cs.querydsl.model.User;import?org.springframework.data.jpa.repository.JpaRepository;import?org.springframework.data.jpa.repository.JpaSpecificationExecutor;import?org.springframework.data.repository.PagingAndSortingRepository;/**?*?@ClassName:UserDao?*?@Description:TODO?用来继承?Jpa?接口?*?@Author?LinLuoChen?*?@Date?2019/7/10/14:06?*?@Version?V1.0?**/public?interface?UserDao?extends?JpaRepository<User,?String>,?JpaSpecificationExecutor<User>,?PagingAndSortingRepository<User,?String>?{????//?-----}这里我们省略 Service 层 直接看 Impl 接口实现类,这里就先写一个单表查询进行测试
package?com.cs.querydsl.service.impl;import?com.cs.querydsl.dao.UserDao;import?com.cs.querydsl.model.QUser;import?com.cs.querydsl.model.User;import?com.cs.querydsl.service.UserService;import?com.querydsl.core.BooleanBuilder;import?com.querydsl.core.types.Projections;import?com.querydsl.jpa.impl.JPAQueryFactory;import?org.springframework.beans.factory.annotation.Autowired;import?org.springframework.stereotype.Service;import?org.thymeleaf.util.StringUtils;import?javax.annotation.PostConstruct;import?javax.persistence.EntityManager;import?java.util.List;/**?*?@ClassName:UserServiceImpl?*?@Description:TODO?接口实现类?*?@Author?LinLuoChen?*?@Date?2019/7/10/14:09?*?@Version?V1.0?**/@Servicepublic?class?UserServiceImpl?implements?UserService?{????@Autowired????UserDao?userDao;????@Autowired????private?EntityManager?entityManager;????//查询工厂实体????private?JPAQueryFactory?queryFactory;????//实例化控制器完成后执行该方法实例化JPAQueryFactory????@PostConstruct????public?void?initFactory()????{????????queryFactory?=?new?JPAQueryFactory(entityManager);????}????/**?????*?@Description?查询全部?????*?@Author?LinLuoChen?????*?@Date??10:53?????*?@return?java.util.List<com.cs.querydsl.model.User>?????**/????@Override????public?List<User>?findAll(User?user)?{????????//?使用?QueryDSL?进行查询????????QUser?qUser?=?QUser.user;????????//?定于获取条件????????BooleanBuilder?booleanBuilder?=?new?BooleanBuilder();????????//?要查询的条件????????if(!StringUtils.isEmpty(user.getName())){????????????//?放入要查询的条件信息????????????booleanBuilder.and(qUser.name.contains(user.getName()));????????}????????//?queryFactory?是上方定义的工厂实体?????????//?select(生成的实体类的字段).from(生成实体类的名称).where(上方要查询的条件).orderBy(排序).fetch()进行查询????????return?queryFactory.select(qUser)????????????????.from(qUser)????????????????.where(booleanBuilder)????????????????.orderBy(qUser.name.desc())????????????????.fetch();????}}我们直接写一个测试类进行测试
package?com.cs.querydsl;import?com.cs.querydsl.model.User;import?com.cs.querydsl.service.UserService;import?org.junit.Test;import?org.junit.runner.RunWith;import?org.springframework.beans.factory.annotation.Autowired;import?org.springframework.boot.test.context.SpringBootTest;import?org.springframework.test.context.junit4.SpringRunner;import?java.util.List;@RunWith(SpringRunner.class)@SpringBootTestpublic?class?QuerydslApplicationTests?{????@Autowired????UserService?userService;????@Test????public?void?contextLoads()?{????}????/**?????*?@Description?测试查询全部方法?????*?@Author?LinLuoChen?????*?@Date??11:22?????**/????@Test????public?void??QueryDSLTest(){????????User?user?=?new?User();????????List<User>?list?=?userService.findAll(user);????????System.out.println(list);????}}虽然说 QueryDSL 也可以做增删改查,但是个人不建议使用(仅限单表),因为单表操作,其实使用 Jpa 就可以了,包括 Jpa 的动态查询,都是很适合单表的,不管是代码量还是效率个人感觉都比 QueryDSL 要快,尤其是代码量,少了不止一点半点,但是连表操作的话,就比较偏向于 QueryDSL 了,特别好用!!下边是连表操作的 QueryDSL ,另外说一下上边只是演示一下 QueryDSL 的使用方法,单表还是建议用 Jpa 比较快!
---------------------------------------------------- 手动分界线 ----------------------------------------------------
package?com.cs.querydsl.service.impl;import?com.cs.querydsl.dao.LocDao;import?com.cs.querydsl.model.Loc;import?com.cs.querydsl.model.QLoc;import?com.cs.querydsl.model.QUser;import?com.cs.querydsl.service.LocService;import?com.querydsl.core.BooleanBuilder;import?com.querydsl.core.QueryResults;import?com.querydsl.core.Tuple;import?com.querydsl.jpa.impl.JPAQueryFactory;import?org.springframework.beans.factory.annotation.Autowired;import?org.springframework.stereotype.Service;import?org.thymeleaf.util.StringUtils;import?javax.annotation.PostConstruct;import?javax.persistence.EntityManager;import?java.util.List;import?java.util.stream.Collectors;/**?*?@ClassName:LocServiceImpl?*?@Description:TODO?接口实现类?*?@Author?LinLuoChen?*?@Date?2019/7/10/14:09?*?@Version?V1.0?**/@Servicepublic?class?LocServiceImpl?implements?LocService?{????@Autowired????LocDao?locDao;????@Autowired????private?EntityManager?entityManager;????//查询工厂实体????private?JPAQueryFactory?queryFactory;????//实例化控制器完成后执行该方法实例化JPAQueryFactory????@PostConstruct????public?void?initFactory()????{????????queryFactory?=?new?JPAQueryFactory(entityManager);????}????/**?????*?@Description?查询全部?????*?@Author?LinLuoChen?????*?@Date??10:53?????*?@return?java.util.List<com.cs.querydsl.model.Loc>?????**/????@Override????public?List<Loc>?findAll(Loc?loc)?{????????//?使用?QueryDSL?进行查询????????QLoc?qLoc?=?QLoc.loc1;????????QUser?qUser?=?QUser.user;????????//?定于获取条件????????BooleanBuilder?booleanBuilder?=?new?BooleanBuilder();????????//?要查询的条件????????if(!StringUtils.isEmpty(loc.getLoc())){????????????//?放入要查询的条件信息????????????booleanBuilder.and(qLoc.loc.contains(loc.getLoc()));????????}????????//连接查询条件(Loc.id?=?User.id?)????????booleanBuilder.and(qLoc.id.eq(qUser.id));????????//?使用?QueryDSL?进行多表联合查询????????QueryResults<Tuple>?listResult?=?queryFactory????????????????.select(QLoc.loc1,QUser.user)????????????????.from(qLoc,?qUser)//查询两表????????????????.where(booleanBuilder)????????????????.fetchResults();????????//遍历?java8?自带流转换成集合????????List<Loc>?collect?=?listResult.getResults().stream().map(tuple?->?{????????????Loc?lcs?=?tuple.get(qLoc);????????????return?lcs;????????}).collect(Collectors.toList());????????return?collect;????}}源码示例地址:spring-boot-querydsl.zip
原文:https://juejin.cn/post/7095617242385088542
logo设计
创造品牌价值
¥500元起
APP开发
量身定制,源码交付
¥2000元起
商标注册
一个好品牌从商标开始
¥1480元起
公司注册
注册公司全程代办
¥0元起
查
看
更
多
关于QueryDSL 配置和使用(详细)
虽然说 QueryDSL 也可以做增删改查,但是个人不建议使用(仅限单表),因为单表操作,其实使用 Jpa 就可以了,包括 Jpa 的动态查询,都是很适合单表的,不管是代码量还是效率个人感觉都比 QueryDSL 要快,尤其是代码量,少了不止一点半点,但是连表操作的话,就比较偏向于 QueryDSL 了,特别好用!!下边是连表操作的 Quer...
JPA-querydsl增强工具,query-dsl-plus,现在已开源并推送到mvnrepository...
快速使用指南 为了快速上手 Mose-X\/query-dsl-plus,请按照以下步骤进行操作:1. **引入依赖 将 query-dsl-plus 添加至项目依赖中,版本号为 1.0.0-RELEASE。xml cn.ljserver.tool query-dsl-plus 1.0.0-RELEASE 2. **DAO 层集成 继承 QuerydslBinderCustomizer 接口,以实现与 JPA 的集成,...
JPA的使用总结
实体Listener用于记录操作日志,通过监听器配置回调函数注解。乐观锁机制和重试机制对Web MVC开发者支持,包括使用DomainClassConverter、自定义HandlerMethodArgumentResolvers等。Debug日志配置技巧:当需要分析复杂问题时,通过设置logging.level.root=trace查看日志,缩小范围至具体类,如设置logging.level.com.zaxx...
全文检索原理-上篇
在检索玩法方面,从基础操作如使用 `_cat` 命令、索引文档、查询、更新和删除,到高级玩法如利用 QueryDSL 查询语法、聚合操作、映射定义等,Elasticsearch 提供了丰富的功能来满足不同场景需求。中文分词是全文检索中的一大挑战,ES 默认的分词器对中文支持有限。为了解决这个问题,可以安装并配置 ik 分词器...
Java岗位要求那些技术
3、 熟练使用Tomcat、docker、Apache,Nginx等应用和服务器配置;4、 熟练掌握SQL Server\/Mysql\/Oracle等主流数据库中的一种,熟悉SQL编写和优化,能进行数据结构设计;5、 有很强的分析问题和解决问题的能力,有强烈的责任心;6、 规范化的编程风格,较强的独立工作能力和团队协作精神及管理能力,有较好...