Mybatis 结果集的映射方式有几种,并解释每种映射方式如何使用?(面试题)

Mybatis结果集映射方式有两种,分别为 自动映射 和 自定义映射

自动映射【resultType】

自定义映射【resultMap】

一.自动映射与自定义映射

  • 自动映射【resultType】:指的是自动将表中的字段与类中的属性进行关联映射
    • 自动映射解决不了两类问题
      • 多表连接查询时,需要返回多张表的结果集
      • 单表查询时,不支持驼峰式自动映射【不想为字段定义别名】
  • 自定义映射【resultMap】:自动映射解决不了问题,交给自定义映射
  • 注意:resultType与resultMap只能同时使用一个

二.自定义映射-级联映射

Dept类

@Data
public class Dept{
    //部门id和名字
    private Integer deptId;
    private String deptName;
 }

Employee类

@Data
public class Employee{
    private Integer id;        //员工id
    private String lastName;   //员工姓名
    private String email;      //员工邮箱    
    private Double salary;     //员工薪资

    private Dept dept;         //员工所属部门信息的对象属性

mybatis-config.xml

<!-- 自定义映射【员工与部门关系】-->
<!--type 主要查询的数据还是 员工的,所以用 employee-->
    <resultMap id="empAndDeptResyltMap" type="employee">
<!--        定义主键字段与属性关联关系-->
<!--        column 是字段,对应的是数据库的列名, property 是属性,对应的是 类的属性名-->
        <id column="id" property="id"></id>
<!--        定义非主键字段与属性关联关系-->
        <result column="last_name" property="lastName"></result>
        <result column="email" property="email"></result>
        <result column="salary" property="salary"></result>
<!--        为员工所属部门,自定义关联关系-->
<!--        级联映射  员工中的部门对象 dept,对象中的id属性 deptId,所以就有了 dept.deptId -->
        <result column="dept_id" property="dept.deptId"></result>
        <result column="dept_name" property="dept.deptName"></result>
    </resultMap>

    <select id="selectEmpAndDeptByEmpId" resultMap="empAndDeptResyltMap">
#         这个 resultMap 和 上面自定义映射的 resultMap 值一样
        SELECT
            e.`id`,
            e.`email`,
            e.`last_name`,
            e.`salary`,
            d.`dept_id`,
            d.`dept_name`
        FROM
#           表名 ,e d 分别是 表的别名
            tbl_employee e,
            tbl_dept d
        WHERE
#           多表查询的条件
            e.`dept_id` = d.`dept_id`
        AND
            e.`id` = #{empId}
    </select>

三.自定义映射-association映射

  • association 可以解决一对一映射关系【一对多】
  • 实例代码:
<!-- 自定义映射【员工与部门关系】-->
<!--type 主要查询的数据还是 员工的,所以用 employee-->
    <resultMap id="empAndDeptResyltMapAssociation" type="employee">
<!--        定义主键字段与属性关联关系-->
<!--        column 是字段,对应的是数据库的列名, property 是属性,对应的是 类的属性名-->
        <id column="id" property="id"></id>
<!--        定义非主键字段与属性关联关系-->
        <result column="last_name" property="lastName"></result>
        <result column="email" property="email"></result>
        <result column="salary" property="salary"></result>
<!--        为员工所属部门,自定义关联关系-->
<!--        association  -->
        <association property="dept" javaType="属性的类型">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"></result>
        </association>
    </resultMap>

    <select id="selectEmpAndDeptByEmpIdAssociation" resultMap="empAndDeptResyltMapAssociation">
#         这个 resultMap 和 上面自定义映射的 resultMap 值一样
        SELECT
            e.`id`,
            e.`email`,
            e.`last_name`,
            e.`salary`,
            d.`dept_id`,
            d.`dept_name`
        FROM
#           表名 ,e d 分别是 表的别名
            tbl_employee e,
            tbl_dept d
        WHERE
#           多表查询的条件
            e.`dept_id` = d.`dept_id`
        AND
            e.`id` = #{empId}
    </select>

表连接查询会影响性能,如何不使用表连接查询还能进行多表查询?

  • 通过员工id获取员工信息及员工所属的部门信息【分步查询
    • 先通过员工id获取员工信息【id,last_name,email,salary,dept_id】
    • 再通过部门id获取部门信息【dept_id,dept_name】

四.自定义映射-collection映射

Dept类

@Data
public class Dept{
    //部门id和名字
    private Integer deptId;
    private String deptName;

    //一对多【dept -> emp】
    private List<Employee> empList;
 }

定义一对多的关联关系

<!-- 自定义映射【员工与部门关系】-->
<!--type 主要查询的数据还是 部门的,所以用 dept-->
    <resultMap id="deptAndempResultMap" type="dept">
<!--        定义主键字段与属性关联关系-->
<!--        column 是字段,对应的是数据库的列名, property 是属性,对应的是 类的属性名-->
        <id column="dept_id" property="deptId"></id>
<!--        定义非主键字段与属性关联关系-->
        <result column="dept_name" property="deptName"></result>
<!--        为员工所属部门,自定义关联关系-->
        <collection property="empList"
                     ofType="属性的类型">
            <id column="id" property="id"></id>
<!--            定义非主键字段与属性关联关系-->
            <result column="last_name" property="lastName"></result>
            <result column="email" property="email"></result>
            <result column="salary" property="salary"></result>
        </collection>
    </resultMap>

    <select id="selectDeptAndEmpByDeptId" resultMap="deptAndempResultMap">
#         这个 resultMap 和 上面自定义映射的 resultMap 值一样
        SELECT
            e.`id`,
            e.`email`,
            e.`last_name`,
            e.`salary`,
            d.`dept_id`,
            d.`dept_name`
        FROM
#           表名 ,e d 分别是 表的别名
            tbl_employee e,
            tbl_dept d
        WHERE
            e.`dept_id` = d.`dept_id`
        AND
            d.dept_id = #{deptId}
    </select>
  • 通过部门id获取部门信息,及部门所属的员工信息【分步查询
    • 先通过部门id获取部门信息【dept_id,dept_name】
    • 再通过员工id获取员工信息【id,last_name,email,salary,dept_id】

五.ResultMap相关标签及属性

  • resultMap标签:自定义映射标签
    • id属性:定义唯一标识
    • type属性:设置映射类型
  • resultMap子标签
    • id标签:定义主键字段与属性关联关系
    • result标签:定义非主键字段与属性关联关系
      • column属性:定义表中字段名称(数据库列名)
      • property属性:定义类中属性名称
    • association标签:定义一对一的关联关系
      • property:定义关联关系属性
      • javaType:定义关联关系属性的类型
      • select:设置分布查询SQL全路径
      • column:设置分布查询SQL中需要的参数
      • fetchType:设置局部延迟加载【懒加载】是否开启
    • collection标签:定义一对多的关联关系
      • property:定义一对一关联关系属性
      • ofType:定义一对一关联关系属性类型
      • fetchType:设置局部延迟加载【懒加载】是否开启

六.Mybatis 中分布查询

  • 为什么使用分布查询【分步查询优势】?
    • 将多表连接查询,改为【分步单表查询】,从而提高程序运行效率

association分步查询:

<!-- 自定义映射【员工与部门关系】-->
<!--type 主要查询的数据还是 员工的,所以用 employee-->
    <resultMap id="empAndDeptResyltMapAssociationStep" type="employee">
<!--        定义主键字段与属性关联关系-->
<!--        column 是字段,对应的是数据库的列名, property 是属性,对应的是 类的属性名-->
        <id column="id" property="id"></id>
<!--        定义非主键字段与属性关联关系-->
        <result column="last_name" property="lastName"></result>
        <result column="email" property="email"></result>
        <result column="salary" property="salary"></result>
<!--        为员工所属部门,自定义关联关系-->
<!--        分步查询  -->
        <association property="dept"
                     select="另一张表的mapper中查询方法的全路径"
                     column="dept_id 也就是两张表的关联值属性"
                    >
        </association>
    </resultMap>
<!--    先通过员工id获取员工信息【id,last_name,email,salary,dept_id】-->
<!--    再通过部门id获取部门信息【dept_id,dept_name】-->
    <select id="selectEmpAndDeptByEmpIdAssociationStep" resultMap="empAndDeptResyltMapAssociationStep">
#         这个 resultMap 和 上面自定义映射的 resultMap 值一样
        SELECT
            id,
            email,
            last_name,
            salary,
            dept_id
        FROM
#           表名 ,e d 分别是 表的别名
            tbl_employee
        WHERE
            id= #{empId}
    </select>

collection分步查询:

<!-- 自定义映射【员工与部门关系】-->
    <!--type 主要查询的数据还是 员工的,所以用 employee-->
    <resultMap id="deptAndEmpResultMapStep" type="dept">
        <!--        定义主键字段与属性关联关系-->
        <!--        column 是字段,对应的是数据库的列名, property 是属性,对应的是 类的属性名-->
        <id column="dept_id" property="deptId"></id>
        <!--        定义非主键字段与属性关联关系-->
        <result column="dept_Name" property="deptName"></result>
        <!--        为员工所属部门,自定义关联关系-->
        <!--        分步查询  -->
        <collection property="empList"
                    select="另一张表的mapper中查询方法的全路径"
                    column="dept_id 也就是两张表的关联值属性">
        </collection>
    </resultMap>
<!--    通过部门id获取部门信息,及部门所属的员工信息【分步查询】-->
<!--    先通过部门id获取部门信息【dept_id,dept_name】-->
<!--    再通过员工id获取员工信息【id,last_name,email,salary,dept_id】-->
    <select id="selectDeptAndEmpByDeptIdStep" resultMap="deptAndEmpResultMapStep">
        #         这个 resultMap 和 上面自定义映射的 resultMap 值一样
        SELECT
            dept_id,
            dept_name
        FROM
#           表名 ,e d 分别是 表的别名
            tbl_dept
        WHERE
            dept_id= #{deptId}
    </select>

七.Mybatis延迟加载【懒加载】

  • 需要时加载,不需要暂时不加载
    • 优势:提升程序运行效率

全局设置 在分步查询的基础上,可以使用延迟加载来提升查询的效率,只需要在全局的 settings 中进行如下的配置:

 

 ② 局部设置 在 association 标签中也可以设置延迟加载,将覆盖全局配置

 八.扩展

① 如果分步查询时,需要传递给调用的查询中有多个参数,则需要将多个参数封装成 Map 来进行传递,语法如下:{k1 = v1,k2 = v2 ...}

② 在所调用的查询方法取值时,就要参考 Map 的取值方式,需要严格的按照封装 map

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis是一个开源的持久层框架,它可以数据库操作与Java对象之间的映射关系进行配置,简化了数据库操作的编写过程。下面是一些常见的MyBatis面试题及其答案: 1. 什么是MyBatisMyBatis是一个持久层框架,它可以将数据库操作与Java对象之间的映射关系进行配置,简化了数据库操作的编写过程。 2. MyBatis的优点有哪些? - 简化了数据库操作的编写过程,提高了开发效率。 - 提供了灵活的SQL映射配置,可以满足各种复杂的查询需求。 - 支持动态SQL,可以根据不同的条件生成不同的SQL语句。 - 提供了缓存机制,可以提高查询性能。 - 与Spring等框架成较为方便。 3. MyBatis的核心组件有哪些? MyBatis的核心组件包括: - SqlSessionFactory:用于创建SqlSession对象的工厂。 - SqlSession:用于执行SQL语句和管理事务。 - Mapper接口:定义了数据库操作的方法。 - Mapper XML文件:配置了SQL语句和结果映射关系。 4. MyBatis中的动态SQL是什么? 动态SQL是指根据不同的条件生成不同的SQL语句。MyBatis提供了一些标签(如if、choose、foreach等)来实现动态SQL的编写,可以根据条件判断、循环等来动态生成SQL语句。 5. MyBatis的一级缓存和二级缓存有什么区别? - 一级缓存是SqlSession级别的缓存,它默认开启且不可关闭。在同一个SqlSession中,如果执行了相同的查询语句,那么第二次以后的查询会直接从缓存中获取结果,而不会再去数据库查询。 - 二级缓存是Mapper级别的缓存,它可以跨SqlSession共享。当多个SqlSession执行相同的查询语句时,如果开启了二级缓存,那么第二次以后的查询会直接从缓存中获取结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值