iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >使用JPA+querydsl如何实现多条件动态查询
  • 565
分享到

使用JPA+querydsl如何实现多条件动态查询

2024-04-02 19:04:59 565人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录JPAquerydsl多条件动态查询介绍一下querydsl看源码springdataJPA和querydsl什么是SpringDataJPA?什么是QueryDSL?@Mapp

JPA querydsl多条件动态查询

相信很多人在做订单管理的时候会用到多条件的检索,比如说查询订单状态是已支付的,金额在100-200之间的商铺a的已完结的订单,这样的多条件。

实现方式有多种,核心就一个if和判空。今天学习了querydsl,来具体回顾一下。

首先是我做的效果图,我们主要看查询怎么实现的。

在这里插入图片描述

介绍一下querydsl

首先QueryDSL仅仅是一个通用的查询框架,专注于通过Java api构建类型安全sql查询。

其次Querydsl可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。

再然后借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。

开始开发 ,首先是pom依赖

这里要加两个关于querydsl的依赖,jpa和apt,版本是一致的

<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-jpa</artifactId>
			<version>4.2.1</version>
		</dependency>
		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-apt</artifactId>
			<version>4.2.1</version>
		</dependency>

然后是要配置一个插件来生成Q版的实体类,只有Q版的实体类才能参与querydsl的查询

<plugin>
				<groupId>com.querydsl</groupId>
				<artifactId>querydsl-Maven-plugin</artifactId>
				<executions>
					<execution>
						<phase>generate-sources</phase>
						<Goals>
							<goal>jpa-export</goal>
						</goals>
						<configuration>
						
							<targetFolder>target/generated-sources/java</targetFolder>
							<packages>com.jerry.gamemarket.entity</packages>
						</configuration>
					</execution>
				</executions>
			</plugin>
<targetFolder>target/generated-sources/java</targetFolder>

这是生成Q版实体的目标文件夹

<packages>com.jerry.gamemarket.entity</packages>

这是把那些包下的实体生成Q版。 

执行mvn compile之后,就能看到生成Q版实体类。

在这里插入图片描述

在编写具体的查询方法之前我们需要实例化EntityManager对象以及JPAQueryFactory对象,并且通过实例化控制器时就去实例化JPAQueryFactory对象,所以在启动类中引入一个Bean叫JPAQueryFactory加一个EntityManager参数,可以全局使用。

@Bean
	public JPAQueryFactory queryFactory(EntityManager entityManager){
		return new JPAQueryFactory(entityManager);
	}

搜索条件实体类

package com.jerry.gamemarket.dto;
import com.jerry.gamemarket.enums.OrderStatusEnums;
import com.jerry.gamemarket.enums.PayStatusEnums;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import java.math.BigDecimal;

@Data
public class SearchOrderDTO {
    private  String orderId;
    //   private String id;
    private  String buyerName;
    private  String buyerPhone;
    private  String buyerAddress;
    private  String canteenName;
    private BigDecimal maxAmount;
    private BigDecimal minAmount;
    private Integer orderStatus;
    //    默认未支付
    private Integer payStatus;
    private Integer pageNum = 1;
    private Integer pageSize=10;
}

动态搜索实现类中的方法,这里返回类型是 QueryResults,我们了解一下这个特殊的返回类型

看源码

  • results是返回的list数据数组
  • total是总数
  • offset是从哪开始
  • limit是限制条数
//
// Source code recreated from a .class file by IntelliJ idea
// (powered by Fernflower decompiler)
//
package com.querydsl.core;
import com.google.common.collect.ImmutableList;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;
public final class QueryResults<T> implements Serializable {
    private static final long serialVersionUID = -4591506147471300909L;
    private static final QueryResults<Object> EMPTY = new QueryResults(ImmutableList.of(), 9223372036854775807L, 0L, 0L);
    private final long limit;
    private final long offset;
    private final long total;
    private final List<T> results;
    public static <T> QueryResults<T> emptyResults() {
        return EMPTY;
    }
    public QueryResults(List<T> results, @Nullable Long limit, @Nullable Long offset, long total) {
        this.limit = limit != null ? limit.longValue() : 9223372036854775807L;
        this.offset = offset != null ? offset.longValue() : 0L;
        this.total = total;
        this.results = results;
    }
    public QueryResults(List<T> results, QueryModifiers mod, long total) {
        this(results, mod.getLimit(), mod.getOffset(), total);
    }
    public List<T> getResults() {
        return this.results;
    }
    public long getTotal() {
        return this.total;
    }
    public boolean isEmpty() {
        return this.results.isEmpty();
    }
    public long getLimit() {
        return this.limit;
    }
    public long getOffset() {
        return this.offset;
    }
}
 @Override
    public QueryResults<OrderMaster> dymamicQuery(SearchOrderDTO searchOrderDTO) {
        QOrderMaster o = QOrderMaster.orderMaster;
        JPAQuery<OrderMaster> query = jpaQueryFactory.select(o).from(o);
        if (!StringUtils.isEmpty(searchOrderDTO.getOrderId())){
            query.where(o.orderId.like(searchOrderDTO.getOrderId()));
        }
        if (!StringUtils.isEmpty(searchOrderDTO.getBuyerName())){
            query.where(o.buyerName.like("%"+searchOrderDTO.getBuyerName()+"%"));
        }
        if (!StringUtils.isEmpty(searchOrderDTO.getBuyerPhone())){
            query.where(o.buyerPhone.eq(searchOrderDTO.getBuyerPhone()));
        }
        if (searchOrderDTO.getMaxAmount()!=null && searchOrderDTO.getMinAmount()!=null){
            query.where(o.orderAmount.goe(searchOrderDTO.getMinAmount()));
        }
        if (searchOrderDTO.getMaxAmount()!=null && searchOrderDTO.getMinAmount()!=null){
            query.where(o.orderAmount.loe(searchOrderDTO.getMaxAmount()));
        }
        if (searchOrderDTO.getOrderStatus()!=null){
            query.where(o.orderStatus.eq(searchOrderDTO.getOrderStatus()));
        }
        if (searchOrderDTO.getPayStatus()!=null){
            query.where(o.payStatus.eq(searchOrderDTO.getPayStatus()));
        }
        return query.orderBy(o.createTime.desc())
                .offset((searchOrderDTO.getPageNum()-1)*searchOrderDTO.getPageSize())
                .limit(searchOrderDTO.getPageSize())
                .fetchResults();
    }

这些查询中包含了模糊查询,动态查询和分页

最后是Controller中的引用

@PostMapping("/searchorder")
    public QueryResults<OrderMaster> findByCase(@RequestBody SearchOrderDTO searchOrderDTO){
        QueryResults<OrderMaster> queryResults=orderService.dymamicQuery(searchOrderDTO);
        System.out.println(searchOrderDTO);
        System.out.println(queryResults.getResults());
        return queryResults;
    }

整个查询就完成了,怎么去渲染数据就看大家喜好了。

springdataJPA和querydsl

什么是SpringDataJPA?什么是QueryDSL?

SpringDataJPA是对JPA使用的封装(JPA是java持久层api)

QueryDSL是基于各种ORM(对象关系映射)上的一个通用框架。使用其API类库,可以写出java代码的sql

@Mapper 实体-模型映射

在mapper上使用注解 @Mapper(componentModel = "spring", uses = {})

用于映射dto和entity 自动生成mapper实现 完成相互转化

如果dto和entity中的属性名不匹配,需要增加注解

@Mappings({
@Mapping(source = "entity.name", target = "dto属性名")
})

项目整体流程

服务后台中rest包下对外暴露提供restful接口,具体类中引入代理层,该代理层实现dto以及dao层的处理(注入service以及自动生成的mapper映射),由mapper处理dto与entity之间的相互转化,service层操作db(操作方式为jpa)

疑问

代理类中,为什么要通过在构造方法上增加@Autowired注解对mapper和service进行初始化,而不是对要注入的成员变量上增加@Autowired注解,采用构造方法的方式有何优点?

通过相关资料找到其答案:java变量初始化的顺序为:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法–>@Autowired 如果该类中有增加构造方法时,执行构造方法时,成员变量还没有初始化,此时会报错,如果没有构造方法可以在成员变量上增加@Autowired注解来初始化变量。为了避免构造方法初始化的时候,成员变量还没有初始化,所以建议在构造方法上增加@Autowired注解。

项目中QueryDSL仅用于生成q类,并没有用java代码格式的sql呀?为什么只用了spring-data-jpa?

JpaRepository

spring-data-jpa简介,spring整合各种第三方框架,命名格式为spring-data-*,spring整合jpa造就了spring-data-jpa。

repository就是持久层,相当于dao、mapper等,项目中定义各种repository继承JpaRepository就可以使用基本的CRUD。

CrudRepository该接口是spring整合jpa的二级接口,此接口提供了普通的CRUD操作,后续新增PagingAndSortingRepository接口,提供findAll方法的重载方法(支持分页),QueryByExampleExecutor优雅的解决了空指针问题,后续优化为JpaRepository接口,该接口对上个接口方法进行优化,返回值更广泛。

SimpleJpaRepository

该类是JpaRepository接口的具体实现,CRUD操作就是由该类提供的。包括四个成员变量JpaEntityInformation、PersistenceProvider、CrudMethodMetadata、EntityManager。 前三个成员变量是为了获取拼接sql,EntityManager执行该sql。相当于session、sqlSession等

写一个Repository继承JpaRepository之后

可以写其实现类,但是不需要implements关键字去实现,spring-data-jpa会自动识别其关系,也可以不写实现类,在运行时期,SimpleJpaRepository该类就是其实现类,如果写了自定义实现类,就会执行实现类中的逻辑

spring-data-jpa的相关语法

对于多表查询 需要用到Specification匿名内部类,重写其方法。感觉遇到多表查询还是写sql比较直观

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 使用JPA+querydsl如何实现多条件动态查询

本文链接: https://www.lsjlt.com/news/142286.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用JPA+querydsl如何实现多条件动态查询
    目录JPAquerydsl多条件动态查询介绍一下querydsl看源码springdataJPA和querydsl什么是SpringDataJPA?什么是QueryDSL?@Mapp...
    99+
    2024-04-02
  • 怎么使用JPA+querydsl实现多条件动态查询
    这篇文章将为大家详细讲解有关怎么使用JPA+querydsl实现多条件动态查询,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。JPA querydsl多条件动态查询相信很多人在做订单管理的时候会用到多条件的...
    99+
    2023-06-29
  • 使用Spring Data JPA如何实现多条件的分页查询
    使用Spring Data JPA如何实现多条件的分页查询?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。话不多说,请看代码:public Map<String, Obje...
    99+
    2023-05-31
    spring 分页查询 dat
  • Spring Data JPA 如何使用QueryDsl查询并分页
    目录SpringDataJPA使用QueryDsl查询并分页使用QueryDSLSpring Data JPA 使用QueryDsl查询并分页 QProblemPoint qP...
    99+
    2024-04-02
  • linq动态条件查询如何使用
    本篇内容主要讲解“linq动态条件查询如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linq动态条件查询如何使用”吧!1,linq动态条件之构造表达式树private Expr...
    99+
    2023-06-17
  • MybatisPlus实现多条件拼接动态查询
    1、前 言 最近在开发过程中,需要用 MybatisPlus 实现类似以下形式的 SQL 语句,动态拼接多个条件,进行查询。 select *from user_infowhere is_deleted = 0...
    99+
    2023-08-20
    mysql mybatis-plus spring boot
  • 如何实现多条件查询
    这篇文章主要讲解了“如何实现多条件查询”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现多条件查询”吧! 而在对用户进行查...
    99+
    2024-04-02
  • springdata jpa如何使用Example快速实现动态查询功能
    这篇文章将为大家详细讲解有关springdata jpa如何使用Example快速实现动态查询功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Example官方介绍Query by Example (Q...
    99+
    2023-06-25
  • Layui如何实现多条件查询
    这篇文章主要介绍了Layui如何实现多条件查询,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。最近做一个档案系统,发现字段超多带分页的多条件查询(分页需要后端分页,传page给...
    99+
    2023-06-25
  • 详解Spring Data JPA动态条件查询的写法
    我们在使用SpringData JPA框架时,进行条件查询,如果是固定条件的查询,我们可以使用符合框架规则的自定义方法以及@Query注解实现。如果是查询条件是动态的,框架也提供了查询接口。JpaSpecificationExecutor...
    99+
    2023-05-31
    spring data jpa
  • springdata jpa使用Example快速实现动态查询功能
    目录Example官方介绍Example api的组成限制使用测试查询自定匹配器规则补充官方创建ExampleMatcher例子(1.8 lambda)StringMatcher 参...
    99+
    2024-04-02
  • 使用Mybatis如何实现多个控制条件查询
    目录实现多个控制条件查询扩展知识实现多个条件简单查询数据库的字段名和实体类的属性名不一致时实现多个条件复杂查询MyBatis条件查询总结1.if条件语句2.choose(whenot...
    99+
    2024-04-02
  • Linq中怎么实现动态条件查询
    本篇文章给大家分享的是有关Linq中怎么实现动态条件查询,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在开发项目的过程中,我们经常会遇到这样的需求,动态组合条件的查询。比如淘宝...
    99+
    2023-06-17
  • mybatisplus如何实现条件查询
    本篇内容介绍了“mybatisplus如何实现条件查询”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、wapper介绍用mp也可以方便的实...
    99+
    2023-06-30
  • Spring Data JPA实现动态查询的两种方法
    前言一般在写业务接口的过程中,很有可能需要实现可以动态组合各种查询条件的接口。如果我们根据一种查询条件组合一个方法的做法来写,那么将会有大量方法存在,繁琐,维护起来相当困难。想要实现动态查询,其实就是要实现拼接SQL语句。无论实现如何复杂,...
    99+
    2023-05-31
    spring data jpa
  • Spring JPA使用CriteriaBuilder动态构造查询方式
    目录Spring JPA使用CriteriaBuilder动态构造查询JPA CriteriaBuilder中一些运算的使用Spring JPA使用CriteriaBuilder动态...
    99+
    2024-04-02
  • layui多条件查询怎么实现
    在Layui中实现多条件查询可以通过以下步骤实现:1. 在HTML页面中创建一个表单,包含多个输入框或下拉框,用于用户输入查询条件。...
    99+
    2023-09-22
    layui
  • mongodb多条件查询怎么实现
    在 MongoDB 中,可以使用 $and、$or 等逻辑运算符来实现多条件查询。以下是使用 $and 运算符实现多条件查询的示例:...
    99+
    2024-04-10
    mongodb
  • Mybatis-plus动态条件查询QueryWrapper的使用案例
    目录一、queryWrapper介绍二、环境搭建1.创建数据库表并添加几条数据:2.创建Springboot项目三、queryWrapper示例1.案例一:根据name模糊查看未删除...
    99+
    2024-04-02
  • Mybatis 实现动态组装查询条件,仿SQL模式
    目的: 以前比较习惯使用Hibernate,后来觉得mybatis不能按我想要的自动组装为SQL查询条件,所以提供该工具类; 效果图: 如图所示,根据条件自动组装查询条件,下面来...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作