以前在項目中常用單表查詢,在涉及到多個實體間查詢時,每每直接用雲智的綜合查詢庫,怎麼查的,一律不知;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(); } }; }