【MyBatis】高级映射多对一,一对多和延迟加载

简介: 【MyBatis】高级映射多对一,一对多和延迟加载

数据库准备:

1. 多对一:

多个学生对应一个班级(学生表是主表, 班级表是副表)

多种实现方式, 常见的包括三种

  1. 第一种方式: 一条sql语句, 级联属性映射
// StudentMapper.xml
// 一条sql语句, 级联属性映射
<resultMap id="studentResultMap" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    <result property="clazz.cid" column="cid"/>
    <result property="clazz.cname" column="cname"/>
</resultMap>
<select id="selectById" resultMap="studentResultMap">
    select
        s.sid,s.sname,c.cid,c.cname
    from
        stu s left join clazz c on s.cid = c.cid
    where
        s.sid = #{sid}
</select>
// 接口
public interface StudentMapper{
    // 根据id获取学生信息, 同时获取学生关联的班级信息
    // 返回一个学生对象, 但是学生对象当中含有班级对象
    Student selectById(Integer id);
} 
// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student student = mapper.selectById(6);
    System.out.println(student);
    sqlSession.close();
}
  1. 第二种方式: 一条sql语句, association标签
// StudentMapper.xml
// 一条sql语句, association(关联)
<resultMap id="studentResultMapAssociation" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    // association翻译为关联, 一个Student对象关联一个Clazz对象
    // property: 提供要映射的POJO类的属性名
    // javaType: 用来指定要映射的java类型
    <association property="Clazz" javaType="Clazz">
        <id property="cid" column="cid"/>
        <result property="cname" column="cname"/>
    </association>
</resultMap>
<select id="selectByIdAssociation" resultMap="studentResultMapAssociation">
    select
        s.sid,s.sname,c.cid,c.cname
    from
        stu s left join clazz c on s.cid = c.cid
    where
        s.sid = #{sid}
</select>
// 接口
public interface StudentMapper{
    // 根据id获取学生信息, 同时获取学生关联的班级信息
    // 返回一个学生对象, 但是学生对象当中含有班级对象
    // 使用association
    Student selectByIdAssociation(Integer id);
} 
// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student student = mapper.selectByIdAssociation(6);
    System.out.println(student);
    sqlSession.close();
}
  1. 第三种方式: 俩条sql语句, 分布查询(这种方式常用: 优点可复用,支持懒加载)
// StudentMapper.xml
// 一条sql语句, association(关联)
<resultMap id="studentResultMapByStep" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
  // 会将column传给select这条sql语句
    <association property="Clazz"
                 select="ClazzMapper.selectByIdStep2"
                 column="cid"/>
</resultMap>
<select id="selectByIdStep1" resultMap="studentResultMapByStep">
    select sid,sname,cid from stu where sid = #{sid}
</select>
-------------------------------------------------------------------------------------
// ClazzMapper.xml
<select id="selectByIdStep2" resultType="Clazz">
    select cid,cname from clazz where cid = #{cid}
</select>
-------------------------------------------------------------------------------------
// 接口
public interface StudentMapper{
  // 分布查询第一步, 先根据id查询出学生信息
    Student selectByIdStep1(Integer id);
} 
public interface ClazzMapper{
  // 分布查询第二步, 根据cid获取班级信息
  Clazz selectByIdStep2(Integer cid);
}
// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student student = mapper.selectByIdStep1(6);
    System.out.println(student);
    sqlSession.close();
}

2. 延迟加载:

  • 分布查询的好处:
  • 复用性强, 可以重复使用, 大步拆成多个小碎步, 每一个小碎步更加可以重复利用.
  • 可以充分利用他妈的延迟加载/懒加载机制
  • 什么是延迟加载(懒加载), 有什么用?
  • 延迟加载的核心原理是: 用的时候再执行查询语句, 不用的时候不查询.
  • 作用: 提高性能
  • 在mybatis中怎么开启延迟加载?
  • 默认情况下是没有开启懒加载的
  • association标签中添加fetchType="lazy"
  • 这种在association标签中配置fetchType="lazy"是局部的设置, 只对当前的association关联的sql语句起作用
<resultMap id="studentResultMapByStep" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    <association property="Clazz"
                 // 这条sql语句用到的时候再查询
                 select="ClazzMapper.selectByIdStep2"
                 column="cid"
                 fetchType="lazy"/>
</resultMap>
// 如果只需要查看学生的名字
//    那么就不会使用到ClazzMapper.selectByIdStep2语句
// 如果想看班级的名字
//    那么就会执行ClazzMapper.selectByIdStep2语句了

3. 一对多:

一个班级对应多个学生(班级表是主表, 学生表是副表)

一对多的实现, 通常是在一的一方中有List集合属性

一对多的实现通常包括俩种实现方式:

  1. collection

// ClazzMapper.xml
<resultMap id="clazzResultMap" type="Clazz">
    <id property="cid" column="cid"/>
    <result property="cname" column="cname"/>
    // 一对多, 这里的collection是集合的意思
    // ofType属性用来指定集合当中的元素类型
  <collection property="stus //list集合名" ofType="Student">
      <id property="sid" column="sid">
      <result property="sname" column="sname">
  </collection>
</resultMap>
<select id="selectByCollection" resultMap="clazzResultMap">
    select c.cid,c.cname,s.sid,s.sname 
      from clazz c left join stu s on c.cid = s.cid
    where c.cid = #{cid}
</select>
// 接口
public interface ClazzMapper{
  // 根据班级编号查询班级信息
  Clazz selectByCollection(Integer cid);
}
// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Clazz clazz = mapper.selectByCollection(6);
    System.out.println(clazz);
    sqlSession.close();
}
  1. 分布查询(常用)

// StudentMapper.xml
<select id="selectByIdStep2" resultType="Student">
    select * from stu where cid = #{cid}
</select>
-------------------------------------------------------------------------------------
// ClazzMapper.xml
<resultMap id="clazzResultMapStep" type="Clazz">
    <id property="cid" column="cid"/>
    <result property="cname" column="cname"/>
  // 会将column传给select这条sql语句
    <collection property="stus"
                 select="StudentMapper.selectByCidStep2"
                 column="cid"/>
</resultMap>
<select id="selectByIdStep1" resultMap="clazzResultMapStep">
    select cid,cname from clazz where cid = #{cid}
</select>
-------------------------------------------------------------------------------------
// 接口
public interface StudentMapper{
  // 分布查询第二步, 先根据班级编号查询出学生信息
    List<Student> selectByCidStep2(Integer id);
} 
public interface ClazzMapper{
  // 分布查询第一步, 根据班级编号获取班级信息
  Clazz selectByIdStep1(Integer cid);
}
// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Clazz clazz = mapper.selectByIdStep1(6);
    System.out.println(clazz);
    sqlSession.close();
}


相关文章
|
17天前
|
SQL XML Java
七、MyBatis自定义映射resultMap
七、MyBatis自定义映射resultMap
35 6
|
19天前
|
SQL XML Java
八、(了解即可)MyBatis懒加载(或者叫延迟加载)
八、(了解即可)MyBatis懒加载(或者叫延迟加载)
21 1
|
2月前
|
XML Java 数据库连接
Mybatis一对一,一对多关联查询
## MyBatis一对一、一对多关联查询详解 MyBatis是一款优秀的持久层框架,提供了灵活的SQL映射功能,支持复杂的数据库操作。本文将详细介绍MyBatis中一对一和一对多关联查询的实现。 ### 一对一关联查询 一对一关联关系指的是一个表中的一条记录与另一个表中的一条记录相关联。例如,一个用户有一个地址信息。 #### 数据库表设计 假设有两个表:`user`和 `address`。 ``` CREATE TABLE user ( id INT PRIMARY KEY, name VARCHAR(50) ); CREATE TABLE address
56 18
|
4月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
6月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
5月前
|
SQL XML Java
Mybatis中一对一和一对多的处理
这篇文章讲解了在Mybatis中如何处理一对一和一对多的关系映射,包括使用association和collection标签的具体方法。
156 1
|
2月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
95 2
|
5月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
240 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
5月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
157 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
5月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
1085 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个