//dao层  继承 扩展仓库接口JpaSpecificationExecutor   (JPA 2引入了一个标准的API)
public interface CreditsEventDao extends JpaRepository<CreditsEventBean, Integer>, JpaSpecificationExecutor<CreditsEventBean>{}

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/      官方文档 -- 5.5. Specifications!

JpaSpecificationExecutor提供了以下接口:

/**
* Interface to allow execution of {@link Specification}s based on the JPA criteria API.
*
* @author Oliver Gierke
*/
public interface JpaSpecificationExecutor<T> { /**
* Returns a single entity matching the given {@link Specification}.
* 返回与给定的{@link规范}匹配的单个实体
* @param spec
* @return
*/
T findOne(Specification<T> spec); /**
* Returns all entities matching the given {@link Specification}.
* 返回与给定的{@link规范}匹配的所有实体。
* @param spec
* @return
*/
List<T> findAll(Specification<T> spec); /**
* Returns a {@link Page} of entities matching the given {@link Specification}.
* 返回与给定的{@link规范}匹配的实体的{@link页面}。
* @param spec
* @param pageable
* @return
*/
Page<T> findAll(Specification<T> spec, Pageable pageable); /**
* Returns all entities matching the given {@link Specification} and {@link Sort}.
* 返回与给定的{@link规范}和{@link排序}匹配的所有实体。
* @param spec
* @param sort
* @return
*/
List<T> findAll(Specification<T> spec, Sort sort); /**
* Returns the number of instances that the given {@link Specification} will return.
* 返回给定的{@link规范}将返回的实例数量。
* @param spec the {@link Specification} to count instances for
* @return the number of instances
*/
long count(Specification<T> spec);
}

我项目上使用到的实例:

public Page<TestBean> specificationFind(Integer size, Integer page, TestBean test) {
Field[] fields = CreditsEventBean.class.getDeclaredFields(); //通过反射获取实体类的所有属性
Sort sort = new Sort(Direction.ASC, "sort").and(new Sort(Direction.DESC, "cutOffTime"));//排序规则 多条件
Pageable pageable = new PageRequest(page-1, size, sort);//分页
return activityDao.findAll(new Specification<CreditsEventBean>() {// Page<T> findAll(Specification<T> spec, Pageable pageable); 分页加多态查询
@SuppressWarnings("unchecked")//压制警告
@Overridepublic Predicate toPredicate(Root<CreditsEventBean> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Map<String, Object> conditions = null;
try {
conditions = BeanUtils.describe(event);//使用Apache的工具类将实体转换成map
conditions.remove("sort");//去掉某些用不到的字段 比如排序字段等
conditions.remove("maxPlayers");// } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
System.err.println("specificationFind ---bean转map出错");
}
List<Predicate> predicates = new ArrayList<>();//存储查询语句
for (int i = 0; i < fields.length; i++) {//循环bean的所有属性
fields[i].setAccessible(true);//是否允许访问
String name = fields[i].getName();//获取属性名
if(conditions.containsKey(name)) {//查询这个键是否存在与这个属性中
if(ObjectUtils.isEmpty(conditions.get(name))) {//判断这个键的值是否为空
continue;//结束本次循环,进入下一次循环
}
if(name.equals("creditStatus")||name.equals("activityShop")
||name.equals("isShopEvent")||name.equals("isPutaway")) {//这里 等于条件
predicates.add(cb.equal(root.get(name), conditions.get(name)));
                
注意:如果查询的表中有关联的表,可能会报错
原因:可能是bean转map的时候,BeanUtils.describe方法将关联bean没取出来,只是取了关联bean的内存地址并存储为字符串,导致关联bean的数据消失 暴力解决方法:
if(name.equals("关联Bean")) {
predicates.add(cb.equal(root.get(name),filed.get关联Bean()));
}else {
predicates.add(cb.equal(root.get(name), conditions.get(name)));
}

continue;
}else if(name.equals("activityStartCreditsDT")||name.equals("activityEndCreditsDT")
||name.equals("creteateTime")||name.equals("cutOffTime")) {// 这里是between条件
String value = (String) conditions.get(name);
String[] split = value.split(",");//分割
predicates.add(cb.between(root.get(name), split[0], split[1]));
continue; }
predicates.add(cb.like(root.get(name), "%"+conditions.get(name)+"%"));// 这里是 模糊 条件
}
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));//返回结果集
}
}, pageable); }

CriteriaBuilder主要api:

等!

spring jpa 动态查询(Specification)的更多相关文章

  1. spring JPA 动态查询

    没什么好说的,记住就行. 下面是在Service中的方法 Page<TStaff> staffs=dao.findAll(new Specification<TStaff>() ...

  2. Spring JPA 定义查询方法

    Spring JPA 定义查询方法 翻译:Defining Query Methods ​ 存储库代理有两种方式基于方法名派生特定域的查询方式: 直接从方法名派生查询 自定义查询方式 ​ 可用选项基于 ...

  3. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  4. spring data jpa 动态查询(工具类封装)

    利用JPA的Specification<T>接口和元模型就实现动态查询了.但是这样每一个需要动态查询的地方都需要写一个这样类似的findByConditions方法,小型项目还好,大型项目 ...

  5. spring jpa 自定义查询数据库的某个字段

    spring jpa 提供的查询很强大, 就看你会不会用了. 先上代码, 后面在解释吧 1. 想查单个表的某个字段 在repository中 @Query(value = "select i ...

  6. JPA动态查询封装

    一.定义一个查询条件容器 /** * 定义一个查询条件容器 * * @param <T> */ public class Criteria<T> implements Spec ...

  7. Spring Data JPA动态查询(多条件and)

    entity: @Entity @Table(name = "data_illustration") public class Test { @Id @GenericGenerat ...

  8. Spring Data Jpa (二)JPA基础查询

    介绍Spring Data Common里面的公用基本方法 (1)Spring Data Common的Repository Repository位于Spring Data Common的lib里面, ...

  9. Hibernate JPA 动态criteria语句针对null查询条件的特殊处理

    最近原Hibernate项目需要添加一个条件,结构有点类似下面的格式,学生和房间是多对一的关系,现在要查询所有没有房间的学生. Class Student{ @ManyToOne Room room; ...

随机推荐

  1. python中多继承C3算法研究

    在python的面向对象继承问题中,单继承简单易懂,全部接受传承类的属性,并可添加自带属性, 但是,在多继承情况下,会遇到多个被继承者的顺序问题,以及多次继承后查找前几次继承者需求属性时,可能不易发现 ...

  2. ant___令牌过滤器

    令牌过滤器允许我们在复制时过滤文件中的数据.要进行过滤,需要使用一个必须与过滤器任务中的@token @设置匹配的标记.任务使用@作为标记分隔符.为了实现此功能,apache ant提供了使用toke ...

  3. oracle 查询表结构

    SELECT t1.Table_Name AS "表名称", t3.comments AS "表说明", t1.Column_Name AS "字段名 ...

  4. spring(aop面向切面编程)

    aop很早有研究过,但是最近想回顾下,顺便记录下,aop的优点有很多,实用性也很广,就好比最早在公司没有使用aop的时候没个业务层都要写try catch来捕获异常,来处理异常,甚至于记录异常或者日志 ...

  5. spring-cloud-config——Quick Start

    参考资料: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.4.0.RELEASE/single/spring-cl ...

  6. 在pycharm中运行python程序

    安装PyCharm 安装过程取决于您的操作系统: 在Windows上安装PyCharm 运行.exe您已下载的文件,并按照PyCharm安装向导的说明进行操作. 在macOS上安装PyCharm 打开 ...

  7. npm 是干什么的

    网上的 npm 教程主要都在讲怎么安装.配置和使用 npm,却不告诉新人「为什么要使用 npm」.今天我就来讲讲这个话题. 本文目标读者是「不太了解 npm 的新人」,大神您别看了,不然又说我啰嗦了 ...

  8. Petrozavodsk Winter Camp, Day 8, 2014, Rectangle Count

    给一个n*m的格点图,问其中有多少个矩形? $ \sum_{x=1}^{nm} \sum_{ab=x} [a + b \leq n](n - a - b + 1)\sum_{cd=x} [c + d ...

  9. Lua 语言变量

    Lua 变量 变量在使用前,必须在代码中进行声明,即创建该变量.编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值. Lua 变量有三种类型:全局变量.局部变量.表中的域. ...

  10. python3练习-查找文件

    题: 编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径 import os import os.path def find_file(root,pa ...