Mybatis的关联集合映射

这篇博客详细介绍了Mybatis中的关联映射和集合映射,包括关联嵌套select查询和嵌套结果映射,以及集合映射的两种方式。内容涵盖了从数据库设计、实体类创建到Mapper接口和XML配置的实现过程,并提供了性能考虑的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 关联和集合:

public class Emp{
    private Integer id;
    private String name;
    private Dept dept;   //关联   
    private List<Task> tasks;  //Task类表示工作类  
}

2. 关联映射

  1. 作用:关联映射解决的就是将查询出的数据映射到关联对象中

  2. 分类:

    1. 关联嵌套select查询

      1. 在本地创建staff表(id,name,dept_id),dept表(id,name,location)

      2. 在本项目的entity包下创建对应的实体类,注意Staff类中出现Dept dept属性

        @Data
        public class Staff {
            private Integer id;
            private String name;
            private Dept dept;
        }
        @Data
        public class Dept {
            private Integer id;
            private String name;
            private String location;
        }
        
      3. 在mapper包下创建StaffMapper接口,定义抽象方法selectStaffDeptList

        public interface StaffMapper {
        
            /**
             * 查询所有员工信息,包括员工所属部分的详细信息
             * @return
             */
            List<Staff> selectStaffDeptList();
        }
        
      4. 添加StaffMapper.xml文件,在文件中修改namespace的值

        1. 定义resultMap,使用关联嵌套select查询
        2. 定义查询staff的sql语句,查询dept的sql语句
    <!--思路1:先将员工的所有信息查询,然后再根据部门id去查询部门的信息,将查询出的部门信息封装到Dept对象中
    特点:对数据库进行了多次查询 可以使用mybatis关联映射中的 嵌套select查询来实现
        -->
        <resultMap id="staffMap" type="cn.tedu.sysmanagement.entity.mybatistest.Staff">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <!--association:表示关联的对象
             javaType:表示该对象的类型,但是mybatis中经常可以自动推断出类型,所以该属性可以省略
             column:表示再次发起查询时,该属性的值会作为参数传递给下次查询,注意,属性的值为查询出的列名
             select:表示再次发起查询的sql语句的id值-->
            <association property="dept" column="dept_id" select="selectDeptById"></association>
        </resultMap>
        <!--查询所有的员工信息-->
        <select id="selectStaffDeptList" resultMap="staffMap">
            select * from staff
        </select>
    
        <!--根据部门id查询出部门详情-->
        <select id="selectDeptById" resultType="cn.tedu.sysmanagement.entity.mybatistest.Dept">
            select * from dept where id=#{dept_id}
        </select>
    
    1. 测试类测试:

      @Test
      public void selectStaffList(){
          List<Staff> list = staffMapper.selectStaffDeptList();
          list.forEach(staff-> System.err.println(staff));
      }
      
    2. 关联嵌套结果映射

    3. 核心思想:将关联关系从数据库中一次性查出,然后通过resutMap映射到实体对象中

    <!--使用mybatis的嵌套结果映射
    思路2:从数据库中一次性将想要的数据查询,最后由mybatis完成查询出的数据和对象中的属性进行一一映射-->
        <resultMap id="staffMap" type="cn.tedu.sysmanagement.entity.mybatistest.Staff">
            <id property="id" column="staff_id"/>
            <result property="name" column="staff_name"/>
            <association property="dept">
                <id property="id" column="dept_id"/>
                <result property="name" column="dept_name"/>
                <result property="location" column="location"/>
            </association>
        </resultMap>
    
        <select id="selectStaffDeptListResutMap" resultMap="staffMap">
            select
                s.id as  staff_id,
                s.name as staff_name,
                d.id as dept_id,
                d.name as dept_name,
                location
            FROM
                staff s
                    LEFT JOIN
                dept d
                ON
                    s.dept_id=d.id
        </select>
    

3. 集合映射

  1. 作用:集合映射解决的就是将查询的数据映射到集合对象中

  2. 分类:

    1. 嵌套select查询–发起多次sql查询
      1. 步骤:
        1. 在entity包下创建Task类
        2. 在mapper接口中定义抽象方法
        3. 在映射文件中使用嵌套select查询来完成集合映射
          1. 将要用到2组sql语句定义出
          2. 定义resultMap,注意collection标签中的属性
    <!--集合映射
        方式一:嵌套select查询-->
        <resultMap id="staffMap"
        type="cn.tedu.sysmanagement.entity.mybatistest.Staff">
            <id property="id" column="id"></id>
            <result property="name" column="name"></result>
            <!--column:表示作为下次查询的参数,该属性的值与查询出的列名对应
           javaType:表示属性的类型,mybatis通常都可以自动推断出属性的类型,所以可以省略不写
            ofType:表示指出集合中保存元素的类型-->
            <collection property="tasks" column="id"
                ofType="cn.tedu.sysmanagement.entity.mybatistest.Task"
                select="selectTaskByStaffId"/>
        </resultMap>
    
        <select id="selectStaffTaskSelectMap" resultMap="staffMap">
            select id,name from staff
        </select>
    
        <select id="selectTaskByStaffId" resultType="cn.tedu.sysmanagement.entity.mybatistest.Task">
            SELECT * FROM task WHERE staff_id=#{staff_id}
        </select>
    
    1. 嵌套结果映射–一次将所有数据查询,由mybatis去进行一一映射
      1. 通过一个sql来查询出想要的所有字段
      2. 配置resultMap,将查询出的列名与属性名进行一一映射
    <!-- 使用集合映射的嵌套结果映射
        思路:从数据库中一次查询出所有字段,之后由mybatis进行字段和属性的映射-->
        <resultMap id="staffMap" 
        type="cn.tedu.sysmanagement.entity.mybatistest.Staff">
            <id property="id" column="staff_id"/>
            <result property="name" column="staff_name"/>
            <collection property="tasks"
        	ofType="cn.tedu.sysmanagement.entity.mybatistest.Task">
                <id property="id" column="task_id"/>
                <result property="name" column="task_name"/>
            </collection>
        </resultMap>
    
        <select id="selectStaffTaskResultMap" resultMap="staffMap">
            SELECT
                s.id as staff_id,
                s.name as staff_name,
                t.id as task_id,
                t.name as task_name
            FROM
                staff s
                    LEFT JOIN
                task t
                ON
                    s.id = t.staff_id
        </select>
    

注意点:
​ 关于集合映射中的嵌套select查询和嵌套结果映射的选择问题:选择时要考虑性能问题,根据数据库中的具体情况以及具体业务进行选择。

4. mybatis中关联和集合映射总结:

  1. 均分为:嵌套select查询和嵌套结果映射
  2. 嵌套select查询,根据第一次查询的结果,发起第二次查询,涉及参数传递,注意column属性
  3. 嵌套结果映射,通过一次查询将想要的结果查询,交由mybatis对列名和属性进行映射,这种情况下都需要将关联的对象/集合中的对象的属性进行一一映射配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值