Mybatis映射文件(2)

Select元素
<select id="selectById" parameterType="Integer" resultType="employee">
    SELECT * FROM t_employee WHERE id = #{id}
</select>

id:唯一标识符

parameterType:参数类型

resultType:返回值类型

<!--resultType:如果返回的是一个集合,那么要写集合中元素的类型-->
<select id="getEmpsByLastNameLike" resultType="employee">
    SELECT * FROM t_employee WHERE last_name LIKE #{lastName}
</select>

返回一条记录的map:key就是列名,值就是对应的值

<select id="getEmpByIDReturnMap" resultType="Map">
    SELECT * FROM t_employee WHERE id=#{id}
</select>

多条记录封装一个map:Map<Integer,Employee>:键是这条记录的主键,值是封装后的javaBean

//多条记录封装一个map:Map<Integer,Employee>:键是这条记录的主键,值是封装后的javaBean
//告诉mybatis封装这个map的时候使用哪个属性作为map的key
@MapKey("id")
Map<Integer,Employee> getEmpByLastNameLikeReturnMap(String lastName);
<select id="getEmpByLastNameLikeReturnMap" resultType="employee">
    SELECT * FROM t_employee WHERE last_name LIKE #{lastName}
</select>

查出数据封装成什么类型?——列名和属性名不一样

1、别名

2、复合驼峰命名法,则在全局配置文件中开启驼峰命名法

3、resultMap自定义对应

自动封装(映射):

※在全局设置中加上autoMappingBehavior——》开启自动映射

※开启驼峰命名规则映射功能 :mapUnderscoreToCamelCase=true

更多更复杂的则需要自定义resultMap实现高级结果集映射功能。

resultMap

1、resultMap单表

<mapper namespace="dao.EmployeeMapperPlus">

    <!--
    自定义某个javaBean封装(映射)规则
    id:唯一id方便后面引用
    type:自定义规则的Java类型
    -->
    <resultMap id="emp" type="bean.Employee">
        <!--
        id定义主键mybatis会在底层有优化
        指定主键列的封装规则
        column:指定那一列(数据库字段)
        property:指定对应的JavaBean的属性
        -->
        <id column="id" property="id"/>
        <!--定义普通列封装-->
        <result column="last_name" property="lastName"/>
        <!--其他不指定的列也会封装,但是推荐我们只要写resultMap就把所有的映射规则都写上-->
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>

    <!--
   resultType和resultMap只能二选一
   resultMap:自定义结果集映射规则
   -->
    <select id="getEmpById" resultMap="emp">
        SELECT * FROM t_employee WHERE id=#{id}
    </select>
</mapper>

2、resultMap多表级联

建立了Department实体类

<!--
场景1:
查询Employee的同时查询员工对应的部门
Employee==Department
-->
<!--联合查询使用级联属性封装结果(映射结果)-->
<resultMap id="empAnddept1" type="bean.Employee">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    <result column="d_id" property="department.id"/>
    <result column="d_name" property="department.name"/>
</resultMap>

<!--使用association定义关联的单个对象的封装规则-->
<resultMap id="empAnddept2" type="bean.Employee">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    <!--
    association可以指定联合的JavaBean对象
    property="department"指定那个对象是需要联合的对象
    javaType="Department"指定这个属性对象的类型【不能省略】
    -->
    <association property="department" javaType="bean.Department">
        <id column="id" property="id"/>
        <result column="d_name" property="name"/>
    </association>
</resultMap>
<select id="getEmployeeAndDepartment" resultMap="empAnddept2">
    SELECT e.id id,e.last_name last_name,e.email email,e.gender gender,
          e.d_id d_id,d.id did,d.d_name d_name
    FROM t_employee e,t_department d
    WHERE e.d_id=d.id AND e.id=#{id}
</select>
还有一种方法就是分开查询,分别建立员工和部门的借口和映射文件,最后将分别查出的结果合在一起。

<!--
使用association进行分步查询
1、先按照员工id查出员工信息
2、根据员工信息中的d_id值去部门表查出部门信息
3、部门设置到员工中
-->
<resultMap id="empAnddept3" type="bean.Employee">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    <!--
    association定义关联对象的封装规则
    select:表明当前属性是调用select指定方法查出来的结果
    column;指定将那一列的值传给这个方法

    流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,封装给property指定的属性
    -->
    <association property="department" select="dao.DepartmentMapper.getDepartmentById" column="d_id"></association>
</resultMap>
<select id="getEmployeeByIdStep" resultMap="empAnddept3">
    SELECT * FROM t_employee WHERE id=#{id}
</select>

<!--
分步查询可以使用延迟加载:
Employee==》DEpartment
    我们每次查询Employee的时候都将包括Department的所有信息查询出来,比较耗费数据库
    我们希望在使用部门信息的时候再去查询
    分步查询的基础上加上两个配置
在全局配置文件中:
延迟加载功能设置
<setting name="lazyLoadingEnabled" value="true"></setting>
<setting name="aggressiveLazyLoading" value="false"></setting>
-->
3、resultMap处理集合

<!--collection嵌套结果集的方式,定义关联的集合类型元素的封装规则-->
<resultMap id="dept1" type="bean.Department">
    <id column="id" property="id"/>
    <result column="d_name" property="name"/>
    <!--
    collection定义关联集合类型的属性封装
    ofType:指定集合里面元素的类型
    -->
    <collection property="employee" ofType="bean.Employee">
        <!--定义集合中元素的封装规则-->
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </collection>
</resultMap>
<select id="getDepartmentAndEmpsById" resultMap="dept1">
    SELECT d.id id,d.d_name d_name,e.id eid,e.last_name last_name,e.email email,e.gender gender
    FROM t_department d LEFT JOIN t_employee e ON d.id=e.d_id
    WHERE d.id=#{id}
</select>

在集合类型中使用分步和延迟加载

<resultMap id="dept2" type="bean.Department">
    <id column="id" property="id"/>
    <result column="d_name" property="name"/>
    <!--将查询出来的id传给getEmpsByDeptId方法-->
    <collection property="employee"
                select="dao.EmployeeMapperPlus.getEmpsByDeptId" column="id"></collection>
</resultMap>
<select id="getDepartmentAndEmpByIdSteps" resultMap="dept2">
    SELECT * FROM t_department WHERE id=#{id}
</select>
懒加载直接在全局设置中开启或者使用fetchType

<resultMap id="dept2" type="bean.Department">
    <id column="id" property="id"/>
    <result column="d_name" property="name"/>
    <!--
    将查询出来的id传给getEmpsByDeptId方法

    fetchType="lazy":表示使用延迟加载
    fetchType="eager":表示立即使用
    -->
    <collection property="employee"
                select="dao.EmployeeMapperPlus.getEmpsByDeptId" column="id" fetchType="eager"></collection>
    <!--
    如果需要将多列的值传递给getEmpsByDeptId方法
    将多列的值封装成map传递
    column="{key1=column1,key2=column2}"
    -->
    <!--<collection property="employee"
                select="dao.EmployeeMapperPlus.getEmpsByDeptId" column="{id=id,name=name}"></collection>-->
</resultMap>
<select id="getDepartmentAndEmpByIdSteps" resultMap="dept2">
    SELECT * FROM t_department WHERE id=#{id}
</select>

鉴别器:

<!--
<discriminator javaType="">
    <case value=""></case>
</discriminator>
鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装的行为

封装Employee:
    如果查出的是女生,就把部门信息查询出来,否则不查询;
    如果是男生,就把last_name一列的值赋值给email
-->

<resultMap id="empAnddept4" type="bean.Employee">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    <!--
    column:指定判定的列名
    javaType:列值对应的Java类型
    -->
    <discriminator javaType="String" column="gender">
        <!--0代表女生 resultType指定封装的,不能缺少-->
        <case value="0" resultType="bean.Employee">
            <association property="department"  select="dao.DepartmentMapper.getDepartmentById" column="d_id"></association>
        </case>
        <!--1代表男生, 如果是男生,就把last_name一列的值赋值给email-->
        <case value="1" resultType="bean.Employee">
            <id column="id" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="last_name" property="email"/>
            <result column="gender" property="gender"/>
        </case>
    </discriminator>
</resultMap>

原文地址:https://www.cnblogs.com/huangzhe1515023110/p/9276083.html