java 多表查询

栏目: Java · 发布时间: 4年前

内容简介:之前在项目中经常使用单表查询,在涉及到多个实体间查询时,往往直接用云智的综合查询库,怎么查的,一概不知;在写Alice的补考管理时,需求:总成绩小于(成绩设置)及格成绩的显示出来,综合查询库不能使用,因此对多实体之间的查询有了一个初步的了解。

引言

之前在项目中经常使用单表查询,在涉及到多个实体间查询时,往往直接用云智的综合查询库,怎么查的,一概不知;

java 多表查询

在写Alice的补考管理时,需求:总成绩小于(成绩设置)及格成绩的显示出来,综合查询库不能使用,因此对多实体之间的查询有了一个初步的了解。

概述

  • 多表查询需要SpringData提供的 JpaSpecificationExecutor 接口
  • 实体仓库需要继承 JpaSpecificationExecutor

    public interface ScoreRepository extends CrudRepository<Score, Long>, JpaSpecificationExecutor<Score>     {}
  • 实现 JpaSpecificationExecutor 接口中 toPredicate 方法

    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 举例说明:

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

改进

张喜硕组长说:之前那样写不太好,不容易理解。

在构建查询条件是我们还可以这样写:

logger.info("构建查询条件,总成绩低于及格成绩");
Predicate makeupScorePredicate = root.get("totalScore").as(Float.class)
    .lessThan(root.join("courseArrangement")
                   .join("course")
                   .join("scoreSet")
                   .get("passScore").as(Float.class))

这样写是不是就简单明了了呢!很容易看出查询的条件是:总成绩低于及格成绩

总结

平时都是使用云智仓库进行综合查询,没有什么感觉,就是会用,原理也不清楚,总是很模糊;直到有一天迫不得已自己去写了,才会对它了解更深一层。

在此,感谢张喜硕组长

参考代码

/**
     * 根据查询条件返回查询成绩
     *
     * @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();
            }
        };
    }

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

轻资产创业

轻资产创业

蔡余杰 / 广东人民出版社 / 2017-11 / 45.00元

在互联网时代,资金和资源已经不是制约创业的关键因素。如今即便没有充足的资金和资产做后盾,创业梦依旧可以成为现实。相信轻资产创业模式能够帮助众多经营管理者和创业者实现管理与创业的梦想。 轻资产创业存在误区,如何跨过? 如何巧用四大模式让自媒体创业落地? 如何用一个点子引发创意型创业? 如何利用电商平台实现流量为王的营销型创业? 如何巧用知识节点做好知识产型创业? ......一起来看看 《轻资产创业》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具