java 多表查询

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

内容简介:之前在项目中经常使用单表查询,在涉及到多个实体间查询时,往往直接用云智的综合查询库,怎么查的,一概不知;在写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();
            }
        };
    }

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

查看所有标签

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

Hackers

Hackers

Steven Levy / O'Reilly Media / 2010-5-30 / USD 21.99

This 25th anniversary edition of Steven Levy's classic book traces the exploits of the computer revolution's original hackers -- those brilliant and eccentric nerds from the late 1950s through the ear......一起来看看 《Hackers》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具