springjpa动态查询(Specification)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

springjpa动态查询(Specification)
//dao层继承扩展仓库接⼝JpaSpecificationExecutor (JPA 2引⼊了⼀个标准的API)
public interface CreditsEventDao extends JpaRepository<CreditsEventBean, Integer>, JpaSpecificationExecutor<CreditsEventBean>{} 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")//压制警告
@Override public 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:
等!。

相关文档
最新文档