1.多表关系

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构。由于业务之间相互关联,所以各个表结构之间也存在着各种联系。

多表关系分为三种:一对多,一对一,多对多

一对多

场景:部门与员工的关系(一个部门下有多个员工)

实现一对多:

在数据库表中多的一方,添加字段,来关联一的一方的主键。

多表问题分析:

现象:部门数据可以直接删除,然而还有部分员工归属于该部门下,此时就出现了数据的不完整、不一致问题

原因:目前上述的两张表,在数据库层面,并未建立关联,所以是无法保证数据的一致性和完整性的

解决方案:外键约束

可以在创建表时或者表结构创建完成后,为字段添加外键约束:

语法

物理外键:使用foreign key定义外键关联另外一张表

逻辑外键:在业务层逻辑中,解决外键关联(推荐)

一对一

场景:用户与身份证信息的关系

关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率

实现一对一:

在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

多对多

场景:学生与课程的关系

关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择

实现多对多:

建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

2.案例

需求:根据下方页面原型,设计员工模块涉及到的表结构

多表查询:

指从多张表中查询数据

笛卡尔积:在数学中,两个集合的所有组合情况

例如:集合A(a,b,c),集合B(m,n)

A与B的笛卡尔积:(a,m),(a,n),(b,m),(b,n),(c,m),(c,n)

连接查询:

内连接:相当于查询A、B交集部分数据

        隐式内连接: select字段列表from表1 ,表2 where连接条件...;

        显式内连接:select字段列表from表1 [inner] join表2 on连接条件...;

        给表起别名:select字段列表from表1 [as]别名1,表2 [as]别名2 where条件...;

注:一旦为表指定了别名,就要通过别名来指定字段名,而不能再使用表名了。

外连接:

        左外连接:查询左表所有数据(包括两张表交集部分数据)

                select字段列表from表1 left [outer] join表2 on连接条件...;

        右外连接:查询右表所有数据(包括两张表交集部分数据)

                select字段列表from表1 right [outer] join表2 on连接条件...;

提示:

对于外连接,常用的是左外连接,因为右外连接的SQL也可以改造成为左外连接(两张表调换个顺序)

子查询

SQL语言中嵌套select语句,称为嵌套查询,又称为子查询

语法:select * from t1 where column1 = (select column1 from t2 …);

说明:

子查询外部的语句可以是insert / update / delete / select的任何一个,最常见的是select

分类:

标量子查询:子查询返回的结果为单个值

列子查询:子查询返回的结果为一列

行子查询:子查询返回的结果为一行

表子查询:子查询返回的结果为多行多列

3.员工列表查询

需求:查询所有员工信息,并查询出部门名称

分页查询分析:

前端传递给后端的分页参数:

页码:page   每页展示记录数:pagesize

后端给前端返回的数据:

数据列表:List rows    总记录数:Long  total

原始方式:

三层架构:

代码示例:

PageHelper分页插件方式:

PageHelper是第三方提供的在Mybatis框架中用来实现分页的插件,用来简化分页操作,提高开发效率

两者的对比:

PageHelper使用步骤:

引入依赖->定义mapper接口的查询方法(无需考虑分页)->在service方法中实现分页查询

PageHelper实现机制:

select count(0) from emp e ...

select ... from emp e ... limit ?,?

注:

PageHelper只会对紧跟在其后的第一条SQL语句进行分页处理

4.条件分页查询

要求:

接口文档:

三层架构:

代码示例(用xml映射方式)

日期时间类型参数接收时,需要通过@DateTimeFormat注解指定前端传递的日期格式

@RequestParam注解的使用场景:

        @RequestParam接收请求参数,参数名不一致时

        @RequestParam设置请求参数的默认值

程序优化---请求参数接收优化

如果controller方法的参数较多,且未来可能继续增加,这会使得方法签名变得复杂难以维护,此时可以考虑将多个请求参数封装为一个对象。

请求参数:

/emps?name=张&gender=1&begin=2007-09-01&end=2022-09-01&page=1&pageSize=10

封装为对象:

此时的controller:

程序优化---动态SQL

我们上述的sql语句直接将条件写死了,但是查询条件随着用户输入的条件变化而变化,所以需要用到动态sql来解决

<if>:判断条件是否成立,如果条件为true,则拼接SQL。

<where>:根据查询条件,来生成where关键字,并会自动去除条件前面多余的and或or。

例如:动态查询员工信息

更多推荐