MyBatis多表查询

  • 实现多表查询方式
    • 业务装配.对两个表编写单表查询语句,在业务(Service)把查询的两个结果进行关联.
    • 使用AutoMapping特性,在实现两表联合查询时通过别名完成映射.
    • 使用 MyBatis 的标签进行实现.
  • 多表查询时,类中包含另一个类的对象的分类
    • 单个对象
    • 集合对象

      resultMap 标签

<-resultMap>标签写在mapper.xml中,由程序员控制SQL查询结果与实体类的映射关系.

默认 MyBatis 使用 AutoMapping 特性.

使用<-resultMap>标签时,<-select>标签不写 resultType 属性,而是使用 resultMap 属性引用<-resultMap>标签.

使用 resultMap 实现单表映射关系

  • 数据库设计

  • 实体类设计

  • TeacherMapper.xml代码

resultMap 实现关联单个对象(N+1 方式)

N+1 查询方式,先查询出某个表的全部信息,根据这个表的信息查询另一个表的信息.

  • <-association> 装配一个对象时使用
  • property: 对象在类中的属性名
  • select:通过哪个查询查询出这个对象的信息
  • column: 把当前表的哪个列的值做为参数传递给另一个查询
  • 与业务装配的区别:

    • 在 service 里面写的代码,由 mybatis 完成装配
  • 实现步骤:

    • 在 Student 实现类中包含了一个 Teacher 对象

    • 在 TeacherMapper 中提供一个查询

    • 在 StudentMapper 中

- **大前提使用 N+1 方式.时如果列名和属性名相同可以不配置,使用 Automapping 特性.但是 mybatis 默认只会给列专配一次。也就是需要把当前表的某列数据传给另个查询的列不能省略不配值**

  ![](https://gitee.com/kylincw/images/raw/master/img/20200405114222.png)

resultMap 实现关联单个对象(联合查询方式)

只需要编写一个 SQL,在 StudentMapper 中添加下面效果

<-association/>只要专配一个对象就用这个标签

此时把<-association/>小的<-resultMap>看待

javaType 属性:<-association/>专配完后返回一个什么类型的对象.取值是一个类(或类的别名)

N+1 方式和联合查询方式对比

N+1:需求不确定时.

联合查询:需求中确定查询时两个表一定都查询.

  • N+1 名称由来
    • 举例:学生中有 3 条数据
    • 需求:查询所有学生信息级授课老师信息
    • 需要执行的 SQL 命令
      • 查询全部学生信息:select*from 学生
      • 执行 3 遍 select*from 老师 whereid=学生的外键
      • 使用多条 SQl 命令查询两表数据时,如果希望把需要的数据都查询出来,需要执行 N+1 条 SQl 才能把所有数据库查询出来.
      • 缺点:效率低
      • 优点:如果有的时候不需要查询学生时同时查询老师.只需要执行一个 select*fromstudent;
      • 适用场景: 有的时候需要查询学生同时查询老师,有的时候只需要查询学生.
  • 如何解决 N+1 查询带来的效率低的问题
    • 默认带的前提: 每次都是两个都查询.
    • 使用两表联合查询.

resultMap查询关联集合对象(N+1)

  • 在 Teacher 中添加 List<-Student>

  • 在 StudentMapper.xml 中添加通过 tid 查询

  • 在 TeacherMapper.xml 中添加查询全部

  • <-collection/> 当属性是集合类型时使用的标签.

resultMap实现加载集合数据(联合查询方式)

mybatis 可以通过主键判断对象是否被加载过.不需要担心创建重复 Teacher

AutoMapping 结合别名实现多表查询

只能使用多表联合查询方式.

要求:查询出的列别和属性名相同

.在 SQL 是关键字符,两侧添加反单引号