全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Spring Data JPA实现动态查询的两种方法

前言

一般在写业务接口的过程中,很有可能需要实现可以动态组合各种查询条件的接口。如果我们根据一种查询条件组合一个方法的做法来写,那么将会有大量方法存在,繁琐,维护起来相当困难。想要实现动态查询,其实就是要实现拼接SQL语句。无论实现如何复杂,基本都是包括select的字段,from或者join的表,where或者having的条件。在Spring Data JPA有两种方法可以实现查询条件的动态查询,两种方法都用到了Criteria API。

Criteria API

这套API可用于构建对数据库的查询。

类型安全。通过定义元数据模型,在程序编译阶段就可以对类型进行检查,不像SQL需要与Mysql进行交互后才能发现类型问题。

如下即为元数据模型。创建一个元模型类,类名最后一个字符为下划线,内部的成员变量与UserInfo.class这个实体类的属性值相对应。

@StaticMetamodel(UserInfo.class)
public class UserInfo_ {
  public static volatile SingularAttribute<UserInfo, Integer> userId;
  public static volatile SingularAttribute<UserInfo, String> name;
  public static volatile SingularAttribute<UserInfo, Integer> age;
  public static volatile SingularAttribute<UserInfo, Long> high;
}

可移植。API并不依赖具体的数据库,可以根据数据库类型的不同生成对应数据库类型的SQL,所以其为可移植的。

面向对象。Criteria API是使用的是各种类和对象如CriteriaQuery、Predicate等构建查询,是面向对象的。而如果直接书写SQL则相对于面向的是字符串。

第一种:通过JPA的Criteria API实现

  1. EntityManager获取CriteriaBuilder
  2. CriteriaBuilder创建CriteriaQuery
  3. CriteriaQuery指定要查询的表,得到Root<UserInfo>,Root代表要查询的表
  4. CriteriaBuilder创建条件Predicate,Predicate相对于SQL的where条件,多个Predicate可以进行与、或操作。
  5. 通过EntityManager创建TypedQuery
  6. TypedQuery执行查询,返回结果
public class UserInfoExtendDao {

 @PersistenceContext(unitName = "springJpa")
 EntityManager em;

 public List<UserInfo> getUserInfo(String name,int age,int high) {
   CriteriaBuilder cb = em.getCriteriaBuilder();
   CriteriaQuery<UserInfo> query = cb.createQuery(UserInfo.class);

   //from
   Root<UserInfo> root = query.from(UserInfo.class);

   //where
   Predicate p1 = null;
   if(name!=null) {
     Predicate p2 = cb.equal(root.get(UserInfo_.name),name);
     if(p1 != null) {
       p1 = cb.and(p1,p2);
     } else {
       p1 = p2;
     }
   }

   if(age!=0) {
     Predicate p2 = cb.equal(root.get(UserInfo_.age), age);
     if(p1 != null) {
       p1 = cb.and(p1,p2);
     } else {
       p1 = p2;
     }
   }

   if(high!=0) {
     Predicate p2 = cb.equal(root.get(UserInfo_.high), high);
     if(p1 != null) {
       p1 = cb.and(p1,p2);
     } else {
       p1 = p2;
     }
   }
   query.where(p1);

   List<UserInfo> userInfos = em.createQuery(query).getResultList();
   return userInfos;
 }
}

第二种:DAO层接口实现JpaSpecificationExecutor<T>接口

JpaSpecificationExecutor如下,方法参数Specification接口有一个方法toPredicate,返回值正好是Criteria API中的Predicate,而Predicate相对于SQL的where条件。与上一个方法相比,这种写法不需要指定查询的表是哪一张,也不需要自己通过Criteria API实现排序和分页,只需要通过新建Pageable、Sort对象并传参给findAll方法即可,简便一些。

public interface JpaSpecificationExecutor<T> {
 T findOne(Specification<T> spec);
 List<T> findAll(Specification<T> spec);
 Page<T> findAll(Specification<T> spec, Pageable pageable);
 List<T> findAll(Specification<T> spec, Sort sort);
 long count(Specification<T> spec);
}

UserInfoDao实现JpaSpecificationExecutor

public interface UserInfoDao 
  extends PagingAndSortingRepository<UserInfo, String>, JpaSpecificationExecutor<UserInfo> {}

实现Specification

public static Specification<UserInfo> getSpec(final String name,final int age,final int high) {
   return new Specification<UserInfo>() {
     @Override
     public Predicate toPredicate(Root<UserInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
       Predicate p1 = null;
       if(name!=null) {
         Predicate p2 = cb.equal(root.get(UserInfo_.name),name);
         if(p1 != null) {
           p1 = cb.and(p1,p2);
         } else {
           p1 = p2;
         }
       }

       if(age!=0) {
         Predicate p2 = cb.equal(root.get(UserInfo_.age), age);
         if(p1 != null) {
           p1 = cb.and(p1,p2);
         } else {
           p1 = p2;
         }
       }

       if(high!=0) {
         Predicate p2 = cb.equal(root.get(UserInfo_.high), high);
         if(p1 != null) {
           p1 = cb.and(p1,p2);
         } else {
           p1 = p2;
         }
       }

       return p1;
     }
   };
 }

项目代码:springdatajpademo_jb51.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# spring  # data  # jpa  # 动态  # jpa动态查询  # 查询  # spring data jpa使用详解(推荐)  # Spring Data Jpa的四种查询方式详解  # Spring Data JPA实现动态条件与范围查询实例代码  # Spring Data JPA 实现多表关联查询的示例代码  # Spring Data JPA 复杂/多条件组合分页查询  # Spring Data Jpa 复杂查询方式总结(多表关联及自定义分页)  # Spring Data JPA调用存储过程实例代码  # Spring Data JPA的作用和用法小结  # 的是  # 相对于  # 面向对象  # 都是  # 也不  # 会有  # 多个  # 不需要  # 两种  # 下划线  # 不像  # 分页  # 就可  # 只需要  # 可以实现  # 这套  # 有两种  # 都用  # 可以根据  # 以对 


相关文章: 中山网站制作网页,中山新生登记系统登记流程?  在线教育网站制作平台,山西立德教育官网?  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  python的本地网站制作,如何创建本地站点?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  行程制作网站有哪些,第三方机票电子行程单怎么开?  建站之星如何快速更换网站模板?  建站主机无法访问?如何排查域名与服务器问题  高性能网站服务器配置指南:安全稳定与高效建站核心方案  网页设计与网站制作内容,怎样注册网站?  官网自助建站平台指南:在线制作、快速建站与模板选择全解析  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  简历在线制作网站免费,免费下载个人简历的网站是哪些?  网站制作新手教程,新手建设一个网站需要注意些什么?  制作网站外包平台,自动化接单网站有哪些?  网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?  如何选择美橙互联多站合一建站方案?  深圳网站制作的公司有哪些,dido官方网站?  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  ,南京靠谱的征婚网站?  西安专业网站制作公司有哪些,陕西省建行官方网站?  南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?  上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  建站之星代理平台如何选择最佳方案?  如何在阿里云服务器自主搭建网站?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  动图在线制作网站有哪些,滑动动图图集怎么做?  建站之星多图banner生成与模板自定义指南  香港服务器建站指南:外贸独立站搭建与跨境电商配置流程  Android滚轮选择时间控件使用详解  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  文字头像制作网站推荐软件,醒图能自动配文字吗?  如何在宝塔面板中创建新站点?  浅析上传头像示例及其注意事项  如何用低价快速搭建高质量网站?  手机网站制作与建设方案,手机网站如何建设?  如何在Golang中指定模块版本_使用go.mod控制版本号  网站制作话术技巧,网站推广做的好怎么话术?  如何通过IIS搭建网站并配置访问权限?  建站之星如何实现网站加密操作?  如何通过建站之星自助学习解决操作问题?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  建站之星如何实现PC+手机+微信网站五合一建站?  建站DNS解析失败?如何正确配置域名服务器?  如何用已有域名快速搭建网站?  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  如何快速搭建二级域名独立网站?  网站制作报价单模板图片,小松挖机官方网站报价?  广州营销型建站服务商推荐:技术优势与SEO优化解析 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。