以前在项目中常用单表查询,在涉及到多个实体间查询时,每每直接用云智的综合查询库,怎么查的,一律不知;less
在写Alice的补考管理时,需求:总成绩小于(成绩设置)及格成绩的显示出来,综合查询库不能使用,所以对多实体之间的查询有了一个初步的了解。ide
JpaSpecificationExecutor
接口实体仓库须要继承JpaSpecificationExecutor
ui
public interface ScoreRepository extends CrudRepository<Score, Long>, JpaSpecificationExecutor<Score> {}
实现JpaSpecificationExecutor
接口中toPredicate
方法this
public static Specification<Score> base(final Map<String, Object> map) { return new Specification<Score>() { @Override public Predicate toPredicate(Root<Score> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {} }
logger.info("构建查询条件,总成绩低于及格成绩"); Predicate makeupScorePredicate = criteriaBuilder .lessThan(root.get("totalScore").as(Float.class), root.join("courseArrangement") .join("course") .join("scoreSet") .get("passScore").as(Float.class));
and
、 or
链接查询条件在此以and
举例说明:spa
private Predicate predicate = null; private CriteriaBuilder criteriaBuilder; private void andPredicate(Predicate predicate) { // 若是传入查询条件不为空 if (null != predicate) { if (null == this.predicate) { // 若是该方法以前没有查询条件,则直接赋值 this.predicate = predicate; } else { // 不然,使用criteriaBuilder的与将已有查询条件和新查询条件用and链接 this.predicate = this.criteriaBuilder.and(this.predicate, predicate); } } }
张喜硕组长说:以前那样写不太好,不容易理解。code
在构建查询条件是咱们还能够这样写:继承
logger.info("构建查询条件,总成绩低于及格成绩"); Predicate makeupScorePredicate = root.get("totalScore").as(Float.class) .lessThan(root.join("courseArrangement") .join("course") .join("scoreSet") .get("passScore").as(Float.class))
这样写是否是就简单明了了呢!很容易看出查询的条件是:总成绩低于及格成绩接口
平时都是使用云智仓库进行综合查询,没有什么感受,就是会用,原理也不清楚,老是很模糊;直到有一天无可奈何本身去写了,才会对它了解更深一层。
在此,感谢张喜硕组长ip
/** * 根据查询条件返回查询成绩 * * @param map 查询条件 */ public static Specification<Score> base(final Map<String, Object> map) { return new Specification<Score>() { private Predicate predicate = null; private CriteriaBuilder criteriaBuilder; // 设置and谓语.注意,这里只能设置and关系的谓语,若是谓语为OR,则须要手动设置 private void andPredicate(Predicate predicate) { if (null != predicate) { if (null == this.predicate) { this.predicate = predicate; } else { this.predicate = this.criteriaBuilder.and(this.predicate, predicate); } } } @Override public Predicate toPredicate(Root<Score> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { logger.info("设置私有变量"); this.criteriaBuilder = criteriaBuilder; logger.info("总评低于及格成绩"); Predicate makeupScorePredicate = criteriaBuilder.lessThan(root.get("totalScore").as(Float.class), root.join("courseArrangement").join("course").join("scoreSet").get("passScore").as(Float.class)); this.andPredicate(makeupScorePredicate); if (null != map.get("semesterId")) { logger.info("传入了学期信息"); Predicate semesterIdPredicate = criteriaBuilder.equal(root.join("courseArrangement").join("semester").get("id").as(Long.class), map.get("semesterId")); this.andPredicate(semesterIdPredicate); } if (null != map.get("gradeId")) { logger.info("传入了年级信息"); Predicate gradeIdPredicate = criteriaBuilder.equal(root.join("student").join("klass").join("grade").get("id").as(Long.class), map.get("gradeId")); this.andPredicate(gradeIdPredicate); } if (null != map.get("majorId")) { logger.info("传入了专业信息"); Predicate majorIdPredicate = criteriaBuilder.equal(root.join("courseArrangement").join("course").join("major").get("id").as(Long.class), map.get("majorId")); this.andPredicate(majorIdPredicate); } if (null != this.predicate) { criteriaQuery.where(criteriaBuilder.and(this.predicate)); } return criteriaQuery.getRestriction(); } }; }