iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Jpa Specification怎么实现and和or同时使用查询
  • 110
分享到

Jpa Specification怎么实现and和or同时使用查询

2023-06-25 17:06:28 110人浏览 八月长安
摘要

这篇文章主要为大家展示了“Jpa Specification怎么实现and和or同时使用查询”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Jpa Specification怎

这篇文章主要为大家展示了“Jpa Specification怎么实现and和or同时使用查询”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Jpa Specification怎么实现and和or同时使用查询”这篇文章吧。

同时使用and和or的查询

UserServiceImpl 类,service实现类

import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.jpa.domain.Specification;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional; import javax.persistence.criteria.CriteriaBuilder;import javax.persistence.criteria.CriteriaQuery;import javax.persistence.criteria.Predicate;import javax.persistence.criteria.Root;import java.util.ArrayList;import java.util.List; @Service@Transactionalpublic class UserServiceImpl implements UserService {    @Autowired    private RongUserRepository rongUserRepository;     //FriendNumResult  自定的返回类型    //FriendNumParam  自定义的封装参数的类型    //RongUser  实体类型    @Override    public FriendNumResult friendNum(FriendNumParam friendNumParam) {        FriendNumResult friendNumResult=new FriendNumResult();         Specification<RongUser> specification = new Specification<RongUser>(){             @Override            public Predicate toPredicate(Root<RongUser> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {                //封装and语句                List<Predicate> listAnd = new ArrayList<Predicate>();                //这里是hql,所以root.get(),方法里面必须是对应的实体属性                listAnd.add(criteriaBuilder.equal(root.get("perLevel").as(Integer.class), friendNumParam.getPerLevel()));                Predicate[] array_and=new Predicate[listAnd.size()];                Predicate Pre_And = criteriaBuilder.and(listAnd.toArray(array_and));                 //封装or语句                List<Predicate> listOr = new ArrayList<Predicate>();                listOr.add(criteriaBuilder.equal(root.get("fId").as(Integer.class), friendNumParam.getUid()));                listOr.add(criteriaBuilder.equal(root.get("fId2").as(Integer.class), friendNumParam.getUid()));                Predicate[] arrayOr = new Predicate[listOr.size()];                Predicate Pre_Or = criteriaBuilder.or(listOr.toArray(arrayOr));                 return criteriaQuery.where(Pre_And,Pre_Or).getRestriction();                //单独使用  and 或者  or 时 返回                //return criteriaBuilder.and(list.toArray());            }        };        long num=this.rongUserRepository.count(specification);        friendNumResult.setFriendNum(Integer.valueOf((int)num));        return friendNumResult;    }}

RongUserRepository接口

import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.JpaSpecificationExecutor;//RongUser  自己的实体类型public interface RongUserRepository extends JpaRepository<RongUser,Integer> , JpaSpecificationExecutor<RongUser> {}

注意:使用Specification之前,RongUserRepository接口必须实现JpaSpecificationExecutor<RongUser>,RongUser对应表的实体类

JPA 动态查询之AND、OR结合使用

现在,我负责开发项目中,使用JPA作为ORM框架。有了JPA,一行sql都没写过。在昨天,有一个新的需求,需要进行动态查询,这个简单。但是有一个地方需要AND、OR结合使用,这里,我将记录下我的理解与写法,希望能帮助到大家。

问题描述

需要根据条件进行动态查询,实现一条类似下文的语句:

SELECT *FROM   tableWHERE  1 = 1   if (a == 1)        AND table.column1 = a   if (b != null)        AND table.column2 = b   if (cList != null && cList.size() > 0)        AND table.column3 IN cList   if (d == 2 || dd == 2)        AND (table.column4 = d OR table.column5 = dd)

上面是几行伪代码。意思是,几个条件之间是AND连接,但是其中的部分条件,是使用OR连接的。

在我们的实际项目中,这个场景也是很常见的。这里,我将分享下具体的写法。以我们项目中的例子为例。

代码示例

JPA的动态查询,这里我们使用的方式是:实现 Specification 接口,自定义动态查询逻辑。这也是我个人比较推荐的方式。JPA的使用、Specification 接口基础知识这里我就不讲了。有兴趣的朋友可以查阅官方文档学习。

下面,我们首先定义好我们的数据库实体:

@Data@Entity@Table(name = "user")public class User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Integer id;        private String username;        private Integer age;        private Date birthDay;        private Integer deleteFlag;}

然后定义好DAO层接口:

@Repositorypublic interface UserDAO extends JpaRepository<User, Long> {        List<User> findAll(Specification<User> querySpec);}

下面是前端传过来的动态查询的参数对象:

@Datapublic class UserDTO {        private String username;        private List<String> userIdList;        private List<Integer> ageList;        @JSONFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")    private Date birthDayBegin;        @jsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")    private Date birthDayEnd;}

然后,重要的地方来了,我们实现 Specification 接口,定义查询逻辑:

在实际代码操作中,我会将这部分逻辑抽离为一个单独的方法,使用lambda表达式完成,其实也就是匿名内部类。

private Specification<User> getListSpec(UserDTO userDTO) {    return (root, criteriaQuery, criteriaBuilder) -> {        List<Predicate> predicateList = new ArrayList<>();        // 未删除标识,只查询未删除的数据        predicateList.add(criteriaBuilder.equal(root.get("deleteFlag"), 0));        // 根据 用户名 或 年龄List 查询        List<Predicate> usernameOrAgePredicate = new ArrayList<>();        String username = userDTO.getUsername();        if (!StringUtils.isEmpty(username)) {            // 用户名这里,用模糊匹配            usernameOrAgePredicate.add(criteriaBuilder.like(root.get("username"), "%" + username + "%"));        }        List<Integer> ageList = userDTO.getAgeList();        if (!CollectionUtils.isEmpty(ageList)) {            // 下面是一个 IN查询            CriteriaBuilder.In<Integer> in = criteriaBuilder.in(root.get("age"));            ageList.forEach(in::value);            usernameOrAgePredicate.add(in);        }                predicateList.add(criteriaBuilder.or(usernameOrAgePredicate.toArray(new Predicate[0])));        // 用户ID List,IN 查询        List<Integer> userIdList = reqDTO.getUserIdList();        if (!CollectionUtils.isEmpty(userIdList)) {            CriteriaBuilder.In<Integer> in = criteriaBuilder.in(root.get("id"));            userIdList.forEach(in::value);            predicateList.add(in);        }        // 生日时间段查询        Date birthDayBegin = reqDTO.getBirthDayBegin();        Date birthDayEnd = reqDTO.getBirthDayEnd();        if (birthDayBegin != null && birthDayEnd != null) {            // DateUtils 是我自定义的一个工具类            Date begin = DateUtils.startOfDay(birthDayBegin);            Date end = DateUtils.endOfDay(birthDayEnd);            predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("birthDay"), begin));            predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("birthDay"), end));        }        // 最终,使用AND 连接 多个 Predicate 查询条件        return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));    };}

这样,我们的动态查询部分就构建完毕了。具体怎么使用呢?如下:

Specification<User> querySpec = this.getListSpec(userDTO);List<User> userList = userDAO.findAll(querySpec);

就这样,我们就执行了一次动态查询,并获取到了结果。

上面的动态查询,实际上等价于下面的伪代码:

SELECT * FROM   user WHERE  user.deleteFlag = 0 AND    ( user.username like '%{username}%' OR user.age IN ageList )AND    user.id IN userIdListAND    user.birthDay > birthDayBegin AND user.birthDay < birthDayEnd ;

当前,需要对应值不为空,才会拼接相应的AND条件。

以上是“Jpa Specification怎么实现and和or同时使用查询”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Jpa Specification怎么实现and和or同时使用查询

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

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

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

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

下载Word文档
猜你喜欢
  • Jpa Specification怎么实现and和or同时使用查询
    这篇文章主要为大家展示了“Jpa Specification怎么实现and和or同时使用查询”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Jpa Specification怎...
    99+
    2023-06-25
  • Jpa Specification如何实现and和or同时使用查询
    目录同时使用and和or的查询JPA 动态查询之AND、OR结合使用问题描述代码示例同时使用and和or的查询 UserServiceImpl 类,service实现类 impo...
    99+
    2024-04-02
  • JPA怎么通过Specification实现复杂查询
    小编给大家分享一下JPA怎么通过Specification实现复杂查询,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!JPA 通过Specification实现复杂查询JPA中继承BaseRepo之后,可以使用最基本的增删改...
    99+
    2023-06-25
  • mysql联合查询中and和or的使用
    这篇文章主要讲解了“mysql联合查询中and和or的使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql联合查询中and和or的使用”吧! 需求...
    99+
    2024-04-02
  • 怎么同时使用JPA和Mybatis
    这篇文章主要讲解了“怎么同时使用JPA和Mybatis”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么同时使用JPA和Mybatis”吧!建模@Entit...
    99+
    2024-04-02
  • mybatis如何使用Criteria的and和or进行联合查询
    目录Criteria的and和or进行联合查询使用criteria 查询xx and ( xx or xx)形式的sqlCriteria的and和or进行联合查询 DemoExa...
    99+
    2024-04-02
  • jpa EntityManager复杂查询怎么实现
    这篇文章主要讲解了“jpa EntityManager复杂查询怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jpa EntityManager复杂查询怎么实现”吧...
    99+
    2023-06-22
  • 怎么使用JPA+querydsl实现多条件动态查询
    这篇文章将为大家详细讲解有关怎么使用JPA+querydsl实现多条件动态查询,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。JPA querydsl多条件动态查询相信很多人在做订单管理的时候会用到多条件的...
    99+
    2023-06-29
  • python中的and和or怎么使用
    在Python中,and和or是逻辑运算符,用于组合多个条件或表达式的结果。 and操作符用于将两个条件或表达式的结果进行逻辑与操作...
    99+
    2024-02-29
    python
  • SpringBoot使用JPA实现查询部分字段
    目录SpringBootJPA查询部分字段自定义简单的查询方法SpringBoot JPA查询部分字段 用过JPA的都知道,只需要继承JpaRepository 根据Jpa的函数命名...
    99+
    2024-04-02
  • oracle中or和and怎么混合使用
    在Oracle中,可以通过使用括号来混合使用OR和AND运算符。例如,假设我们有一个查询条件要求满足A和(B或C):SELEC...
    99+
    2023-08-31
    oracle
  • 【使用 LambdaQueryWrapper 实现嵌套 and 和 or 】在 add 中 循环添加 or
    前言 使用 LambdaQueryWrapper 实现嵌套 and 和 or 使用mybatis-plus 中的 LambdaQueryWrapper 进行查询,在添加查询条件的时候,有时候会需要添加...
    99+
    2023-08-31
    mybatis mysql 数据库
  • Mybatis Criteria使用and和or进行联合条件查询的操作方法
    之前用Mybatis框架反向的实体,还有实体里面的Example,之前只是知道Example里面放的是条件查询的方法,可以一直不知道怎么用,到今天才开始知道怎么简单的用。在我们前台查...
    99+
    2024-04-02
  • 在Spring Boot中使用Spring-data-jpa实现分页查询
    在我们平时的工作中,查询列表在我们的系统中基本随处可见,那么我们如何使用jpa进行多条件查询以及查询列表分页呢?下面我将介绍两种多条件查询方式。1、引入起步依赖   <dependency> <gro...
    99+
    2023-05-31
    spring boot data
  • 使用JPA+querydsl如何实现多条件动态查询
    目录JPAquerydsl多条件动态查询介绍一下querydsl看源码springdataJPA和querydsl什么是SpringDataJPA?什么是QueryDSL?@Mapp...
    99+
    2024-04-02
  • springdata jpa使用Example快速实现动态查询功能
    目录Example官方介绍Example api的组成限制使用测试查询自定匹配器规则补充官方创建ExampleMatcher例子(1.8 lambda)StringMatcher 参...
    99+
    2024-04-02
  • JPA怎么使用findBy方法自定义查询
    这篇文章给大家分享的是有关JPA怎么使用findBy方法自定义查询的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。JPA使用findBy方法自定义查询最近在项目中使用spring boot+jpa的方式来访问数据库...
    99+
    2023-06-21
  • Spring Data JPA怎么使用QueryDsl查询并分页
    小编给大家分享一下Spring Data JPA怎么使用QueryDsl查询并分页,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Spring Data JPA 使用QueryDsl查询并分页 QProblemPo...
    99+
    2023-06-25
  • 怎么使用JPA自定义SQL查询结果
    本篇内容介绍了“怎么使用JPA自定义SQL查询结果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!JPA自定义SQL查询结果很多时候都会遇到自...
    99+
    2023-06-25
  • SpringBoot项目中使用JPA如何实现表关联查询
    SpringBoot项目中使用JPA如何实现表关联查询?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。例子中总共有两个实体类,一个是Floor(商品楼层类),另一个是FloorC...
    99+
    2023-05-31
    springboot jpa 表关联查询
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作