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 ('', 'warrior', '', '渝足');
INSERT INTO `querydsl_demo_student` VALUES ('', 'fury', '', '广工');

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

  3.1 查询所有的数据

    3.1.1 直接利用SpringDataJPA提供的方法实现

      》编写一个Student控制层类

package cn.test.demo.query_demo.controller;

import cn.test.demo.query_demo.dao.StudentJPA;
import cn.test.demo.query_demo.model.javaModel.Student;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource;
import java.util.List; /**
* @author 王杨帅
* @create 2018-03-29 21:25
* @desc 测试控制类
**/
@RestController
@RequestMapping(value = "/test")
@Slf4j
public class TestController { @Resource
private StudentJPA studentJPA; @GetMapping(value = "/connect")
public String connect() {
String resp = "测试类连接成功H ELLO ";
log.error("测试Error");
System.out.println(resp);
return resp;
} @GetMapping(value = "/findAll")
public List<Student> findAll() {
return studentJPA.findAll();
}
}

TestController

      》依赖注入Student持久层JPA

    @Resource
private StudentJPA studentJPA;

      》利用StudentJPA实现查询所有客户信息   

    @GetMapping(value = "/findAll")
public List<StudentModel> findAll() {
List<StudentModel> studentModelList = studentJPA.findAll();
if(studentModelList.isEmpty()) {
// TODO: 抛出自定义异常 -> 无任何学生数据
return null;
} else {
return studentModelList;
}
}
package cn.test.demo.query_demo.controller;

import cn.test.demo.query_demo.dao.StudentJPA;
import cn.test.demo.query_demo.model.javaModel.StudentModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource;
import java.util.List; /**
* @author 王杨帅
* @create 2018-03-30 8:19
* @desc 学生控制层
**/
@RestController
@RequestMapping(value = "/student")
@Slf4j
public class StudentController { @Resource
private StudentJPA studentJPA; @GetMapping(value = "/connect")
public String connect() {
String resp = "Student控制层连接测试";
log.info(resp);
return resp;
} @GetMapping(value = "/findAll")
public List<StudentModel> findAll() {
List<StudentModel> studentModelList = studentJPA.findAll();
if(studentModelList.isEmpty()) {
// TODO: 抛出自定义异常 -> 无任何学生数据
return null;
} else {
return studentModelList;
}
}
}

    3.1.2 利用QueryDSL实现

      》依赖注入实体管理者

    @Autowired
private EntityManager entityManager;

      》声明JPA查询工厂 

    private JPAQueryFactory jpaQueryFactory;

      》实例化JPA查询工厂

        技巧01:@PostConstruct 注解的功能是在类初始化时执行相关的方法,此处是为了在类初始化时就完成JPA查询对象的实例化

    @PostConstruct
public void initFactory() {
jpaQueryFactory = new JPAQueryFactory(entityManager);
log.info("初始化JPA查询工厂成功");
}

      》引入inject依赖

        如果不引入inject依赖,那么在初始化JPA实例化工厂时会出错,错误信息为“找不到相关class文件”

        <dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

      》编写QueryDSL查询

        技巧01:利用和实体类StudentModel对应的查询实体类QStudentModel实例化出一个和实体类StudentModel对应的查询实体对象_Q_StudentModel

        技巧02:在QueryDSL中用到的东西大部分都是和查询实体对象相关的

        技巧03:selectFrom() 方法时指明需要查询的字段以及从个表查询,只不过这里的查询字段以及表都是利用查询实体对象来代替的,而且selectFrom()是select()和from()的结合版本,仅仅限于单表这样使用

        技巧04:fetch()  方法是执行查询并返回查询到的数据集合

        坑01:fetch() 查询到的数据集合和selectFrom() 中指定的查询实体对象对应的数据库实体类型一致;在本案例中fetch() 返回的就是 StudentModel 对象组成的集合

    @GetMapping(value = "/queryAll")
public List<StudentModel> queryAll() {
// 01 使用queryDSL查询
QStudentModel _Q_StudentModel = QStudentModel.studentModel;
// 02 查询并返回结果
return jpaQueryFactory
.selectFrom(_Q_StudentModel)
.orderBy(_Q_StudentModel.id.asc())
.fetch();
}

  3.2 根据ID查询数据

    3.2.1 利用SpringDataJPA提供的方法实现

      》依赖注入 StudnetJPA

    @Autowired
private StudentJPA studentJPA;

      》调用 SpringJPA 提供的方法

    @GetMapping(value = "/queryDetail")
public StudentModel queryDetail(
@RequestParam("id") Long id
) {
System.out.println(studentJPA.findById(id).get());
return studentJPA.findById(id).get();
}

      》效果展示

      

    3.2.2 利用QueryDSL实现

      》依赖注入管理实体

    @Autowired
private EntityManager entityManager;

      》声明JPA查询工厂

private JPAQueryFactory jpaQueryFactory;

      》实例化JPA查询工厂

    @PostConstruct
public void initFactory() {
jpaQueryFactory = new JPAQueryFactory(entityManager);
log.info("初始化JPA查询工厂成功");
}

      》实例化查询对象并调用QueryDSL提供的方法完成查询操作

        技巧01:where() 方法是设定条件的方法

        技巧02:fetchOne() 方法时执行查询并返回一条查询到的第一条记录

    @GetMapping(value = "/queryDetail")
public StudentModel queryDetail(
@RequestParam("id") Long id
) {
log.info("获取到的ID参数为:{}", id);
QStudentModel _Q_studentModel = new QStudentModel("hello");
StudentModel studentModel = jpaQueryFactory
.select(_Q_studentModel)
.from(_Q_studentModel)
.where(_Q_studentModel.id.eq(id))
.fetchOne();
log.info("获取到的数据为:{}", studentModel);
return studentModel;
}

      》效果展示

      

  3.3 更新数据

    3.3.1 利用SpringDataJPA提供的方法实现

      坑01:利用SpringDataJPA提供的save() 方法更新数据时,是根据主键去更新的;需要传入一个对象到save() 方法中去,如果该对象的ID在数据库中不存在就会在数据库中新增一条记录,只用当这个对象的ID在数据库中存在时才会进行数据的更新操作;故:SpringDataJPA提供的save() 方法既可以实现更新操作又可以实现新增操作

      》依赖注入StudnetJPA

    @Autowired
private StudentJPA studentJPA;

      》调用SpringDataJPA的save() 方法

    @PutMapping(value = "/update")
public StudentModel update(
@RequestBody StudentModel studentModel
) {
log.info("获取到的ID参数为:{}", studentModel);
StudentModel result = studentJPA.save(studentModel); log.info("更新后的返回数据为:{}", result);
return result;
}

      》效果展示

        

    3.3.2 利用QueryDSL实现

      》依赖注入实体管理对象

    @Autowired
private EntityManager entityManager;

      》声明JPA查询工厂

    private JPAQueryFactory jpaQueryFactory;

      》初始化JPA查询工厂

    @PostConstruct
public void initFactory() {
jpaQueryFactory = new JPAQueryFactory(entityManager);
log.info("初始化JPA查询工厂成功");
}

      》实例化查询对象并利用QueryDSL相关方法实现

        坑01:利用QueryDSL进行处查询操作外的所有操作都必须添加事物控制注解,否则会报错;如果利用SpringDataJPA的先关方法在不添加事物注解的情况下时不会报错的,由此可见QueryDSL还是比较安全的

        技巧01:update() 方法是指定更新那个数据表,只不过这里是利用查询实体类对象来代替表名

        技巧02:set() 方法是设定更新字段和更新值,参数一是待更新的字段名称,参数2是更新值;只不过更新字段是利用查询实体对象的属性代替

        技巧03:where() 方法是添加条件限制

        技巧04:execute() 方法是执行更新操作,该方法的返回值是一个Long类型,代表更新的记录数

    @Transactional
@PutMapping(value = "/update")
public Long update(
@RequestBody StudentModel studentModel
) {
log.info("获取到的ID参数为:{}", studentModel);
QStudentModel _Q_studentModel = QStudentModel.studentModel;
Long result = jpaQueryFactory.update(_Q_studentModel)
.set(_Q_studentModel.name, studentModel.getName())
.set(_Q_studentModel.address, studentModel.getAddress())
.where(_Q_studentModel.id.eq(studentModel.getId()))
.execute(); log.info("更新的记录数为:{}", result);
return result;
}
package cn.test.demo.query_demo.controller;

import cn.test.demo.query_demo.dao.StudentJPA;
import cn.test.demo.query_demo.model.javaModel.QStudentModel;
import cn.test.demo.query_demo.model.javaModel.StudentModel;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional; /**
* @author 王杨帅
* @create 2018-03-30 8:19
* @desc 学生控制层
**/
@RestController
@RequestMapping(value = "/student")
@Slf4j
public class StudentController { @Autowired
private StudentJPA studentJPA; @Autowired
private EntityManager entityManager; private JPAQueryFactory jpaQueryFactory; @PostConstruct
public void initFactory() {
jpaQueryFactory = new JPAQueryFactory(entityManager);
log.info("初始化JPA查询工厂成功");
} @GetMapping(value = "/queryAll")
public List<StudentModel> queryAll() {
// 01 使用queryDSL查询
QStudentModel _Q_StudentModel = QStudentModel.studentModel;
// 02 查询并返回结果
return jpaQueryFactory
.selectFrom(_Q_StudentModel)
.orderBy(_Q_StudentModel.id.asc())
.fetch();
} @Transactional
@PutMapping(value = "/update")
public Long update(
@RequestBody StudentModel studentModel
) {
log.info("获取到的ID参数为:{}", studentModel);
QStudentModel _Q_studentModel = QStudentModel.studentModel;
Long result = jpaQueryFactory.update(_Q_studentModel)
.set(_Q_studentModel.name, studentModel.getName())
.set(_Q_studentModel.address, studentModel.getAddress())
.where(_Q_studentModel.address.eq(studentModel.getAddress()))
.execute(); log.info("更新的记录数为:{}", result);
return result;
} }

  3.4 删除数据

    3.4.1 利用SpringDataJPA提供的方法实现

      》SpringDataJPA提供了多种删除方法,常用的有下面三种方法

        deleteById() -> 根据ID删除 -> 需要传入一个ID作为参数

        delete() -> 根据实体类对象删除 -> 需要传入一个实体对象作为参数

        deleteAll() -> 删除所有数据 -> 不需要传入任何参数

      》依赖注入StudnetJPA

    @Autowired
private StudentJPA studentJPA;

      》调用SpringDataJPA的deleteById方法

    @DeleteMapping(value = "/delete")
public void delete(@RequestParam("id") Long id) {
log.info("获取到的参数为:{}", id);
studentJPA.deleteById(id);
}

    3.4.2 利用QueryDSL提供的方法实现

      》前面三个步骤照旧

      》实例化查询实体对象并调用QueryDSL提供的方法实现删除操作

    @Transactional
@DeleteMapping(value = "/delete")
public Long delete(@RequestParam("age") Long age) {
log.info("获取到的参数为:{}", age);
QStudentModel _Q_studentModel = QStudentModel.studentModel;
Long result = jpaQueryFactory.delete(_Q_studentModel)
.where(_Q_studentModel.age.lt(age))
.execute();
log.info("删除的记录数为:{}", result);
return result;
}
package cn.test.demo.query_demo.controller;

import cn.test.demo.query_demo.dao.StudentJPA;
import cn.test.demo.query_demo.model.javaModel.QStudentModel;
import cn.test.demo.query_demo.model.javaModel.StudentModel;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional; /**
* @author 王杨帅
* @create 2018-03-30 8:19
* @desc 学生控制层
**/
@RestController
@RequestMapping(value = "/student")
@Slf4j
public class StudentController { @Autowired
private StudentJPA studentJPA; @Autowired
private EntityManager entityManager; private JPAQueryFactory jpaQueryFactory; @PostConstruct
public void initFactory() {
jpaQueryFactory = new JPAQueryFactory(entityManager);
log.info("初始化JPA查询工厂成功");
} @GetMapping(value = "/queryAll")
public List<StudentModel> queryAll() {
// 01 使用queryDSL查询
QStudentModel _Q_StudentModel = QStudentModel.studentModel;
// 02 查询并返回结果
return jpaQueryFactory
.selectFrom(_Q_StudentModel)
.orderBy(_Q_StudentModel.id.asc())
.fetch();
} @Transactional
@PutMapping(value = "/update")
public Long update(
@RequestBody StudentModel studentModel
) {
log.info("获取到的ID参数为:{}", studentModel);
QStudentModel _Q_studentModel = QStudentModel.studentModel;
Long result = jpaQueryFactory.update(_Q_studentModel)
.set(_Q_studentModel.name, studentModel.getName())
.set(_Q_studentModel.address, studentModel.getAddress())
.where(_Q_studentModel.address.eq(studentModel.getAddress()))
.execute(); log.info("更新的记录数为:{}", result);
return result;
} @Transactional
@DeleteMapping(value = "/delete")
public Long delete(@RequestParam("age") Long age) {
log.info("获取到的参数为:{}", age);
QStudentModel _Q_studentModel = QStudentModel.studentModel;
Long result = jpaQueryFactory.delete(_Q_studentModel)
.where(_Q_studentModel.age.lt(age))
.execute();
log.info("删除的记录数为:{}", result);
return result;
} }

   

    

SpringBoot12 QueryDSL01之QueryDSL介绍、springBoot项目中集成QueryDSL的更多相关文章

  1. 在前后端分离的SpringBoot项目中集成Shiro权限框架

    参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制   以及跨域的问题也有涉及

  2. springboot项目中集成ip2region遇到的问题及终极解决办法

    1.问题回顾 按照ip2region项目的官方集成到springboot项目后,运行测试一切都ok,没有任何问题.但是当项目打成可执行的jar包后再运行,却显示找不到ip2region.db,无法找到 ...

  3. 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链

    买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...

  4. 后端分页神器,mybatis pagehelper 在SSM与springboot项目中的使用

    mybatis pagehelper想必大家都耳熟能详了,是java后端用于做分页查询时一款非常好用的分页插件,同时也被人们称为mybatis三剑客之一,下面 就给大家讲讲如何在SSM项目和sprin ...

  5. 在SpringBoot项目中添加logback的MDC

    在SpringBoot项目中添加logback的MDC     先看下MDC是什么 Mapped Diagnostic Context,用于打LOG时跟踪一个“会话“.一个”事务“.举例,有一个web ...

  6. 自身使用的springboot项目中比较全的pom.xml

    在学习的时候常建新的项目,mark下商用的jar <dependency> <groupId>org.mybatis</groupId> <artifactI ...

  7. springboot 项目中获取默认注入的序列化对象 ObjectMapper

    在 springboot 项目中使用 @SpringBootApplication 会自动标记 @EnableAutoConfiguration 在接口中经常需要使用时间类型,Date ,如果想要格式 ...

  8. springboot项目中js、css静态文件路径访问

    springboot静态文件访问的问题,相信大家也有遇到这个问题,如下图项目结构. 项目结构如上所示,静态页面引入js.css如下所示. 大家肯定都是这样写的,但是运行的话就是出不来效果,图片也不显示 ...

  9. 解决springboot项目中@Value注解参数值为null的问题

    1.错误场景: springboot项目中在.properties文件(.yml)文件中配置了属性值,在Bean中使用@Value注解引入该属性,Bean的构造器中使用该属性进行初始化,此时有可能会出 ...

随机推荐

  1. java.lang.NoClassDefFoundError: org/apache/jsp/jsp/Container_jsp

    1.错误描述 八月 20, 2014 7:10:18 下午 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.servi ...

  2. jquery对象和js对象的转化

    jquery对象和js对象的转化   jquery对象只能使用jqury方法,不能使用js的方法,相反的,js对象也只能使用js的方法,如果js对象使用了jquery方法,那么浏览器就会报错. 但是在 ...

  3. 求小于n的素数个数

    本文是对 LeetCode Count Primes 解法的探讨. 题目: Count the number of prime numbers less than a non-negative num ...

  4. jquery实现简单的搜索

    对一个简单的ul列表进行输入框的搜索功能,搜索之前及搜索后显示效果如下: 用到的主要jquery技术有filter()和match()方法以及正则匹配,基础HTML+div设置: <div cl ...

  5. 【BZOJ1001】狼抓兔子(网络流)

    [BZOJ1001]狼抓兔子(网络流) 题面 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨, ...

  6. [APIO2015]巴邻旁之桥

    Bzoj权限题 luogu题面 先去掉同边的 首先k==1,即求一个点j 使\(\sum_{i\in A} |D_i - D_j| + \sum_{i\in B} |D_i - D_j|\)最小 因为 ...

  7. 打造MacOS版“XShell”

    1.背景 XShell作为一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议.作为server端开发,几乎是必备工具了. 很多刚 ...

  8. css边框小结

    css边框 CSS对界面的分割如上图,他们的含义如下: contend:包含HTML元素中包含的文本,图像或其他媒体.      padding:内容和边框之间的空格. 你可以想像这样的内在空间.   ...

  9. 如何将VMware虚拟机迁移到AWS

    在工作中,我们一直在努力将我们的一些VMware工作负载转移到AWS,并且我的任务是将几个VMware虚拟机迁移到AWS,作为暂时的概念验证. 在本文中,我将展示如何设置AWS连接器并使用AWS服务器 ...

  10. Unreachable statement

    public boolean onQueryTextSubmit(String s) { if (sv != null) { // 得到输入管理对象 InputMethodManager imm = ...