目录
1.背景
2.QueryDSL简介
3.配置步骤
3.1 pom配置
3.2 添加maven插件
3.3 项目JPA基本配置
3.4 实体类注解配置
4后端写法
4.1持久层写法
4.2服务层写法
4.3控制层写法
5.致谢
项目后端数据持久化之前使用的是JPA的JPQL写法,而JPQL不支持 insert、limit等sql常用函数,给开发造成诸多不便。因此,我们常常使用native sql形式来书写sql语句,来查询和组装我们需要的数据,但是根据实际项目需求,需要灵活选用Mysql、Microsoft sqlserver、Postgresql等数据库管理系统。那么无论是JPQL或者是native sql的写法,在数据库更换后,很容易带来一定的兼容性问题。
QueryDSL是一个通用的查询框架,专注于通过 JavaAPI 构建类型安全的 Sql 查询,也可以说 QueryDSL 是基于各种 ORM 框架以及 Sql 之上的一个通用的查询框架,使用它的API类库可以写出“Java代码的sql”,不用去手动接触sql语句,表达含义却如sql般准确。更重要的一点,我们可以SpringDataJPA + QueryDSL JPA联合使用,它们之间有着完美的相互支持,以达到更高效的编码。
本次配置基于SpringBoot 2.1.4.RELEASE版本
com.querydsl
querydsl-jpa
com.querydsl
querydsl-apt
provided
com.mysema.maven
apt-maven-plugin
1.1.3
process
target/generated-sources/java
com.querydsl.apt.jpa.JPAAnnotationProcessor
添加这个插件是为了生成实体对应的查询类(查询实体,命名方式为:"Q"+对应实体名)。
目前后端使用Nacos发现、配置和管理项目下的各种微服务,在本地开发平台64上有个are-common.yaml作为项目的统一配置的规约,关于JPA的配置如下:
spring:
returnvaluehandlerproxy:
active: "true"
jpa:
#项目目前使用的database为postgresql
database: postgresql
show-sql: true
properties:
open-in-view: true
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
temp:
use_jdbc_metadata_defaults: false
hbm2ddl:
auto: update
在项目java实体类中必须标注注解@Entity,否则apt插件生成查询类失败
在此,介绍各个分层的写法,只是做个样例,大家理解它的思路即可。
import com.abc.mare.common.util.BaseRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface LayoutRepo extends BaseRepository,
JpaSpecificationExecutor,
QuerydslPredicateExecutor {}
在此,向大家推荐一个用于分页查询的Page,PageRequest和Sort,使用起来很方便
引入方式:
import org.springframework.data.domain.*;
接下来,继续介绍服务层写法。
QLayout $ = QLayout.layout;
/**
* @description: 根据筛选条件查询版面列表,筛选条件后续加版面名称和维护人
* @author: liu
* @create: 2022/6/27 15:23
* @param pageSize 页面条数
* @param currentPage 当前页面
* @param parameter 某一筛选查询的字段
* @param sortAttribute 排序字段
* @param orderDirection 排序顺序
* @return Page
*/
@Override
@Transactional
public Page getAllByCondition(int pageSize, int currentPage, String parameter, String sortAttribute, String orderDirection) {
BooleanBuilder condition = new BooleanBuilder();
if (!StringUtils.isEmpty(parameter)) {
//$.name对应当前实体类对应的这个字段,等同于select * from table where name=parameter
//(这里contains做的是模糊查询,也可以eq()实现精确查询)
condition.and($.name.contains(parameter.trim()));
}
Sort sortObject = null;
if (StringUtils.isEmpty(sortAttribute)) {
sortObject = new Sort(Sort.Direction.DESC, Constant.maintenanceTime);
} else {
sortObject = new Sort(Sort.Direction.fromString(orderDirection), sortAttribute);
}
PageRequest pageRequest = PageRequest.of(currentPage - 1, pageSize, sortObject);
return layoutRepo.findAll(condition, pageRequest);
}
在控制层我们可以使用Page
QueryDSL可以搭配实体类中的逻辑外键关联注解,实现更为复杂的inner join、left join和right join,详细用法我还需要进一步整理,感兴趣的大家可以一块交流。
最后,由于本人技术有限,难免出现错误,在此欢迎各位小伙伴们指正并勘误,谢谢大家。