java 多表查詢

引言

以前在項目中常用單表查詢,在涉及到多個實體間查詢時,每每直接用雲智的綜合查詢庫,怎麼查的,一律不知;less

clipboard.png

在寫Alice的補考管理時,需求:總成績小於(成績設置)及格成績的顯示出來,綜合查詢庫不能使用,所以對多實體之間的查詢有了一個初步的瞭解。ide

概述

  • 多表查詢須要SpringData提供的JpaSpecificationExecutor接口
  • 實體倉庫須要繼承JpaSpecificationExecutorui

    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));

andor鏈接查詢條件

在此以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();
            }
        };
    }
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息