首页 > 作文

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

更新时间:2023-04-06 03:21:54 阅读: 评论:0

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 arch。

开始开发 ,首先是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-ma数字聊大ven-plugin</artifactid><executions><execution><pha>generate-sources</pha><goals><goal>jpa-export</goal></goals><configuration><targetfolder>target/generated-sources/java</targetfolder><packages>com.jerry.gamemarket.entity</packages></co以案促改剖析材料nfiguration></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参数,可以全局使用。

@beanpublic jpaqueryfactory queryfactory(entitymanager entitymanager){return new jpaqueryfactory(entitymanager);}

搜索条件实体类

package com.jerry.gamemarket.dto;import com.jerry.gamemarket.enums.orderstatunums;import com.jerry.gamemarket.enums.paystatunums;import lombok.data;import org.springframework.context.annotation.bean;import java.math.bigdecimal;/** * author by 李兆杰 * date 2018/11/28 */@datapublic class archorderdto {    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是总数offt是从哪开始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.rializable;import java.util.list;import javax.annotation.nullable;public final class queryresults<t> implements rializable {    private static final long rialversionuid = -4591506147471300909l;    private static final queryresults<object> empty = new queryresults(immutablelist.of(), 9223372036854775807l, 0l, 0l);    private final long limit;    private final long offt;    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 offt, long total) {        this.limit = limit != null ? limit.longvalue() : 9223372036854775807l;        this.offt = offt != null ? offt.longvalue() : 0l;        this.total = total;        this.results = results;    }    public queryresults(list<t> results, querymodifiers mod, long total) {        this(results, mod.getlimit(), mod.getofft(), total);    }    public list<t> getresults() {        return this.results;    }    public long gettotal() {        return this.total;    }    public boolean impty() {        return this.results.impty();    }    public long getlimit() {        return this.limit;    }    public long getofft() {        return this.offt;    }}
 @override    public queryresults<ordermaster> dymamicquery(archorderdto archorderdto) {        qordermaster o = qordermaster.ordermaster;        jpaquery<ordermaster> query = jpaqueryfactory.lect(o).from(o);        if (!stringutils.impty(archorderdto.getorderid())){            query.where(o.orderid.like(archorderdto.getorderid()));        }        if (!stringu西欧封建制度tils.impty(archorderdto.getbuyername())){            query.where(o.buyername.like("%"+archorderdto.getbuyername()+"%"));        }        if (!stringutils.impty(archorderdto.getbuyerphone())){            query.where(o.buyerphone.eq(archorderdto.getbuyerphone()));        }        if (archorderdto.getmaxamount()!=null && archorderdto.getminamount()!=null){            query.where(o.orderamount.goe(archorderdto.getminamount()));        }        if (archorderdto.getmaxamount()!=null && archorderdto.getminamount()!=null){            query.where(o.orderamount.loe(archorderdto.getmaxamo星星之火歌词unt()));        }        if (archorderdto.getorderstatus()!=null){            query.where(o.orderstatus.eq(archorderdto.getorderstatus()));        }        if (archorderdto.getpaystatus()!=null){            query.where(o.paystatus.eq(archorderdto.getpaystatus()));        }        return query.orderby(o.createtime.desc())                .offt((archorderdto.getpagenum()-1)*archorderdto.getpagesize())                .limit(archorderdto.getpagesize())                .fetchresults();    }

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

最后是controller中的引用

@postmapping("/archorder")    public queryresults<ordermaster> findbyca(@requestbody archorderdto archorderdto){        queryresults<ordermaster> queryresults=orderrvice.dymamicquery(archorderdto);        system.out.println(archorderdto);        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”, us = {})

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

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

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

项目整体流程

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

疑问

代理类中,为什么要通过在构造方法上增加@autowired注解对mapper和rvice进行初始化,而不是对要注入的成员变量上增加@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接口,该接口对上个接口方法进行优化,返回值更广泛。

simplejparepos电子鸽钟itory

该类是jparepository接口的具体实现,crud操作就是由该类提供的。包括四个成员变量jpaentityinformation、persistenceprovider、crudmethodmetadata、entitymanager。 前三个成员变量是为了获取拼接sql,entitymanager执行该sql。相当于ssion、sqlssion等

写一个repository继承jparepository之后

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

spring-data-jpa的相关语法

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。

本文发布于:2023-04-06 03:21:53,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/e55283f33e7977eeba1311ed532c520a.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:使用JPA+querydsl如何实现多条件动态查询.doc

本文 PDF 下载地址:使用JPA+querydsl如何实现多条件动态查询.pdf

标签:方法   变量   初始化   接口
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图