SpringBoot12 QueryDSL01之QueryDSL介绍、springBoot项目中集成QueryDSL
1 QueryDSL介绍
1.1 背景
QueryDSL的诞生解决了HQL查询类型安全方面的缺陷;HQL查询的扩展需要用字符串拼接的方式进行,这往往会导致代码的阅读困难;通过字符串对域类型和属性的不安全引用又是HQL面临的问题。
随着类型安全的域模型给软件开发带来的巨大好处,域的更改可以直接反应在查询上,而且随着域的更改查询也会自动随着改变。(即:同一套查询,只需要通过改变域就可以实现不同的查询)
针对Hibernate的HQL是Querydsl的第一个目标语言,但现在它支持JPA,JDO,JDBC,Lucene,Hibernate Search,MongoDB,Collections和RDFBean作为后端。
1.2 原则
1.2.1 类型安全
查询是根据生成的查询类型进行构建的,这些生成的查询类型反映了你域类型的属性。调用相关查询方法来构建查询时也是完全以一种类型安全的方式进行
1.2.2 一致性
查询的路径和操作在所有的实例中都是一样使用,查询接口也有一个通用的接口
1.3 JPA
Querydsl定义了用于在持久化域模型数据之上查询的一般静态类型语法,JPA是QueryDSL的主要集成技术之一
jpa -> 点击前往
2 在springBoot项目中集成QueryDSL
2.1 软件版本说明
2.2 创建SpringBoot项目
利用IDEA创建一个SpringBoot项目,并添加web、jpa、mysql依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.test.demo</groupId> <artifactId>query_demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>query_demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
pom.xml
2.2.1 修改maven配置
将maven配置成自己的
2.2.2 配置数据连接
坑01:如果现在直接启动项目的会回报错,报错信息如下,报错的原因是我们导入了JPA和mysql这两个和数据库相关的依赖,但是我们并没有在项目中配置先关的连接信息
server: servlet: context-path: /dev port: 9998 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/springboot?useUnicode=true&characterEncoding=UTF-8&&useSSL=false driver-class-name: com.mysql.jdbc.Driver username: root password: 182838 # jpa: # database: mysql # properties: # hibernate: # show-sql: true # format-sql: true jpa: database: mysql show-sql: true
2.2.3 编写一个控制类,启动项目
package cn.test.demo.query_demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 王杨帅 * @create 2018-03-29 21:25 * @desc 测试控制类 **/ @RestController @RequestMapping(value = "/test") public class TestController { @GetMapping(value = "connect") public String connect() { String resp = "测试类连接成功"; System.out.println(resp); return resp; } }
TestController
到这里,整个SpringBoot项目就已经搭建成功啦,下面就开始在SpringBoot项目中集成QueryDSL框架
2.3 配置项目热部署
参考博文:点击前往
2.3.1 引入lombok
lombok提供了一些简化代码的方式,例如:get/set直接利用注解实现、提供了self4j日志
参考博文:点击前往
2.4 集成QueryDSL
2.4.1 引入QueryDSL相关依赖
<dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${querydsl.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>${querydsl.version}</version> </dependency>
2.4.2 配置Maven APT插件
QueryDSL框架会利用maven的插件来根据标注了@Entity的实体类生成该实体类对应的查询类型
<!--添加QueryDSL插件支持--> <plugin> <groupId>com.mysema.maven</groupId> <artifactId>apt-maven-plugin</artifactId> <version>1.1.3</version> <executions> <execution> <goals> <goal>process</goal> </goals> <configuration> <outputDirectory>target/generated-sources/java</outputDirectory> <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor> </configuration> </execution> </executions> </plugin>
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.test.demo</groupId> <artifactId>query_demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>query_demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--lombok相关--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--热部署相关--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!--QueryDSL相关--> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${querydsl.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>${querydsl.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> <!--添加QueryDSL插件支持--> <plugin> <groupId>com.mysema.maven</groupId> <artifactId>apt-maven-plugin</artifactId> <version>1.1.3</version> <executions> <execution> <goals> <goal>process</goal> </goals> <configuration> <outputDirectory>target/generated-sources/java</outputDirectory> <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
pom.xml
2.4.3 在数据库创建一个测试表
DROP TABLE IF EXISTS `querydsl_demo_student`; CREATE TABLE `querydsl_demo_student` ( `id` int(36) NOT NULL, `name` varchar(10) NOT NULL, `age` int(3) NOT NULL, `address` varchar(24) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/* Navicat MySQL Data Transfer Source Server : mysql5.4 Source Server Version : 50540 Source Host : localhost:3306 Source Database : springboot Target Server Type : MYSQL Target Server Version : 50540 File Encoding : 65001 Date: 2018-03-29 22:01:47 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `querydsl_demo_student` -- ---------------------------- DROP TABLE IF EXISTS `querydsl_demo_student`; CREATE TABLE `querydsl_demo_student` ( `id` int(36) NOT NULL, `name` varchar(10) NOT NULL, `age` int(3) NOT NULL, `address` varchar(24) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of querydsl_demo_student -- ---------------------------- INSERT INTO `querydsl_demo_student` VALUES ('1', 'warrior', '12', '渝足'); INSERT INTO `querydsl_demo_student` VALUES ('2', 'fury', '24', '广工');
student.sql
2.4.4 根据数据库表创建对应的实体类
package cn.test.demo.query_demo.model.javaModel; import lombok.Data; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; /** * @author 王杨帅 * @create 2018-03-29 21:52 * @desc 学生实体类 **/ @Entity @Data @Table(name = "querydsl_demo_student") public class Student implements Serializable { @Id private Long id; private String name; private Integer age; private String address; }
2.4.5 创建JPA基本接口
所有其它的持久层JPA接口都通过集成该接口
技巧01:@NoRepositoryBean 注解是排除该基础接口被实例化
坑01:如果不添加@NoRepositoryBean 注解会报错
package cn.test.demo.query_demo.dao; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.NoRepositoryBean; /** * @author 王杨帅 * @create 2018-03-29 21:5 * @desc jpa基础接口 **/ @NoRepositoryBean public interface BaseJPA<T> extends JpaRepository<T,Long>, JpaSpecificationExecutor<T>, QuerydslPredicateExecutor<T> { }
2.4.6 创建逻辑JPA
技巧01:这里和原生的JPA写法大致相同,只不过我们在这里利用基本JPA做了已成封装而已
package cn.test.demo.query_demo.dao; import cn.test.demo.query_demo.model.javaModel.Student; /** * @author 王杨帅 * @create 2018-03-29 22:07 * @desc **/ public interface StudentJPA extends BaseJPA<Student> { }
2.4.7 利用IDEA生成查询实体
坑01:如果导入了QueryDSL相关依赖,而且在项目中有@Entity标注的实体类,在没有实现实体类对应的查询类型时启动项目时会报错,报错信息为:找不到XX查询实体
3 利用QueryDSL实现单标的CRUD
待更新……
2018-3-29 22:17:17