应用背景
一般我们在开发数据量不是很大的中小型企业系统来说,直接使用SQL关联,多表联合查询就可以了,因为这样在项目开发过程中非常的高效。但是一旦在遇到大数据量的背景前提下,原始的关联查询方式逐渐的显现出了越来越多的弊端。
我们引入海尔电商技术总监Richie的观点来说,主要有以下几点:
从逻辑架构分层原则来看
关联关系代表了业务规则/逻辑,毫无约束大量使用关联查询,就是把大量的业务规则和逻辑放在数据库来执行了,数据库消耗cpu、内存、io等资源进行关联操作,实际上是在做应用该做的事情。
从资源利用率方面看
大部分场景下,并不是所有关联查询的结果都被有效使用了。例如后台管理的列表界面,通常都会分页显示,关联查询的结果集,只有当前页的数据被使用,其他都是无用的,但数据库需要消耗额外资源得到全部结果集,再从中得到当前页数据。
从架构的伸缩性方面看
大量的关联查询会导致集中式的数据库架构很难向分布式架构转换,伸缩性方面的优化难度高。
总结:
关联查询方便快速,开发效率比较好,如果系统、数据库经过一些垂直优化手段完全能够满足性能要求是可以使用的,例如中小企业的内部管理系统等。
不使用关联查询在架构层面有很多优点,但对系统分析和设计、开发能力要求高。一般在互联网行业等用户数较多的情况下最好重视这方面。
理论上不存在什么复杂场景,如果不使用数据库的关联查询就无法满足需求的。巨无霸的ERP系统SAP,基本整个系统功能都是用单表查询实现的。
代码实现
从前面的介绍中我们了解到,很多高性能的应用都会对关联查询进行分解。简单的来说,可以对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。
比如说下面截图中的数据就是利用这种原理实现的。
下面我以实际的代码为例来进行说明,其中由于数据均为模拟数据,所以说我直接通过手写的方式代替数据库查询来给结果集进行赋值。
join()
实现多表关联filter()
实现where查询listPage()
实现数据分页功能。
实体类
Class
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class Class {
private String id;
private String name;
}
Student
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class Student {
private String id;
private String name;
private String classId;
}
PageQuery
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@ApiModel(value =