Java里面的引入Query类_在Spring Data JPA中引入Querydsl的实现方式

一、环境说明

基础框架采用Spring Boot、Spring Data JPA、Hibernate。在动态查询中,有一种方式是采用Querydsl的方式。

二、具体配置

1、在pom.xml中,引入相关包和配置插件。

(1)引入包(注:不需要版本号,Spring Boot 会自动匹配合适的版本)

com.querydsl

querydsl-jpa

com.querydsl

querydsl-apt

(2)配置插件:主要用来生成“查询对象”。

com.mysema.maven

maven-apt-plugin

1.0.4

generate-sources

process

target/generated-sources

com.querydsl.apt.jpa.JPAAnnotationProcessor

2、设置源文件夹

经过上面pom.xml的配置后,就在 target/generated-sources 文件夹下面自动生成“查询对象”。需要将该文件夹设置成“源文件夹”,以便可以将下面的java文件进行编译使用。

生成的查询对象,都是在原实体(bo)类的名字前,加上 Q 表示。

5f2a3ad5fa3c470b8dffbe66595dfe10.png

3、dao中继承接口QueryDslPredicateExecutor

94fee079c89acf687ef55543ba316859.png

4、在service层使用 Querydsl方式进行是查询,例如:

d352afa1f00821d74418cb7c3c1c75c0.png

三、写在最后

此文仅作为引入Querydsl的笔记,并不代表作者本人推荐使用Querydsl。就实际应用而言,个人更倾向于使用 JPA Criteria 的方式来实现动态查询,其接口是JpaSpecificationExecutor。

补充:Spring-data-jpa扩展查询 QueryDSL 实践

说明: QueryDSL是以函数连接的方式将SQL调用进行拆分,比较spring data jpa中的criteria查询方法还是简洁了不少。

用例:通过服务调用,使用querydsl进行查询并直接返回DTO对象(自定义传输对象(根据业务需求),注意区别于Entity)

实践步骤:

1.创建user与depart表,使用外键进行关联,并插入一些模拟数据。

8364c4d8f4f23106ed4abe95f8b8ccbe.png

2.创建sprintboot项目,在pom文件中加入以下依赖:

com.querydsl

querydsl-jpa

com.querydsl

querydsl-apt

provided

3.在pom文件中-->节点下加入plugin:

com.mysema.maven

apt-maven-plugin

1.1.3

process

target/generated-sources/java

com.querydsl.apt.jpa.JPAAnnotationProcessor

com.querydsl

querydsl-apt

4.1.3

4.生成相关entity与repository对象,这里以user为例:

注意:repository需要继承 QueryDslPredicateExecutor接口。

5.生成业务传输对象DTO:

package com.test.demo.db;

//

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;

import static javax.persistence.GenerationType.IDENTITY;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

/**

* User generated by hbm2java

*/

@Entity

@Table(name = "user", catalog = "testdb")

public class User implements java.io.Serializable {

private Integer id;

private Department department;

private String username;

public User() {

}

public User(Department department, String username) {

this.department = department;

this.username = username;

}

@Id

@GeneratedValue(strategy = IDENTITY)

@Column(name = "id", unique = true, nullable = false)

public Integer getId() {

return this.id;

}

public void setId(Integer id) {

this.id = id;

}

@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = "fk_depart")

public Department getDepartment() {

return this.department;

}

public void setDepartment(Department department) {

this.department = department;

}

@Column(name = "username", length = 45)

public String getUsername() {

return this.username;

}

public void setUsername(String username) {

this.username = username;

}

}

package com.test.demo.repo;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import org.springframework.data.querydsl.QueryDslPredicateExecutor;

import org.springframework.stereotype.Repository;

import com.test.demo.db.User;

@Repository

public interface UserRepository extends QueryDslPredicateExecutor, JpaRepository,JpaSpecificationExecutor{

}

注意:repository需要继承 QueryDslPredicateExecutor接口。

5.生成业务传输对象DTO:

package com.test.demo.controller;

import com.querydsl.core.annotations.QueryProjection;

import lombok.Data;

@SuppressWarnings("unused")

public @Data class UserDTO {

private String username;

private String departname;

}

6.创建controller进行测试:

package com.test.demo.controller;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.annotation.PostConstruct;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

import com.querydsl.core.types.Projections;

import com.querydsl.core.types.dsl.BooleanExpression;

import com.querydsl.jpa.impl.JPAQuery;

import com.querydsl.jpa.impl.JPAQueryFactory;

import com.test.demo.db.QUser;

import com.test.demo.repo.UserRepository;

@RestController

@RequestMapping("/")

public class TestController {

@Autowired

UserRepository userRepo;

@Autowired

@PersistenceContext

EntityManager em;

private JPAQueryFactory queryFactory;

@PostConstruct

public void init() {

queryFactory = new JPAQueryFactory(em);

}

@RequestMapping("/users")

Object getUsers(@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,

@RequestParam(value = "size", required = false, defaultValue = "10") Integer size,

@RequestParam(value = "name", required = false) String name,

@RequestParam(value = "depart", required = false) String depart) {

QUser user = QUser.user;

JPAQuery query = queryFactory

.select(Projections.bean(UserDTO.class, user.username, user.department.name.as("departname")))

.from(user);

BooleanExpression pre = null;

if (name!=null && !name.isEmpty()) {

pre = user.username.startsWith(name);

}

if (depart!=null && !depart.isEmpty()) {

pre = user.department.name.startsWith(depart);

}

query.where(pre);

query.limit(size);

query.offset((page-1)*size);

List result = query.fetch();

Map map = new HashMap<>();

map.put("total", userRepo.count(pre));

map.put("data", result);

return map;

}

}

注:这里就是使用querydsl进行查询,并直接转换需要的属性至DTO。并且代码中的pre是可以根据参数动态拼接的。

7.测试结果:

014b384995b089ac026da29471d0bd1f.png

这是查询日志:

0146fb085e74af0d71edee43a7e276f4.png

完。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值