MyBatis(五):自定义映射ResultMap及处理一对多和多对一映射

目录

1.resultmap处理字段与属性的映射关系

2.处理多对一映射

2.1 级联(嵌套查询)

2.2 使用association处理映射关系        

2.3 分布查询

3.处理一对多映射

3.1 collection标签

3.2 分布查询


   之前我们学习的都是字段与实体类属性名一致的情况,接下来就介绍用resultmap处理字段与属性名不匹配的情况和一对多和多对一的映射。

1.resultmap处理字段与属性的映射关系

resultMap:设置自定义映射
子标签还有两个属性:
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名

resultmap
属性含义
id表示自定义映射的唯一标识
type查询的数据要映射的实体类的类型
resultmap的子标签
子标签作用
id设置主键的映射关系
result设置普通字段的映射关
associatio设置多对一的映射关系
collection设置一对多的映射关系

例:字段名和实体类中的属性名不一致

字段:

 实体类:

<!--
resultMap:设置自定义映射 
属性: 
id:表示自定义映射的唯一标识 
type:查询的数据要映射的实体类的类型 
子标签: 
id:设置主键的映射关系 
result:设置普通字段的映射关系

association:设置多对一的映射关系 
collection:设置一对多的映射关系 
属性:
property:设置映射关系中实体类中的属性名 
column:设置映射关系中表中的字段名 
-->

<resultMap id="userMap" type="User"> 
    <id property="id" column="id"></id>
    <result property="userName" column="user_name"></result>
    <result property="password" column="password"></result> 
    <result property="age" column="age"></result> 
    <result property="sex" column="sex"></result> 
</resultMap>
<!--List<User> testMohu(@Param("mohu") String mohu);-->
<select id="testMohu" resultMap="userMap">
    <!--select * from t_user where username like '%${mohu}%'-->
    select id,user_name,password,age,sex from t_user where user_name like concat('%',#{mohu},'%')
</select>

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性

名符合Java的规则(使用驼峰)

此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系

a>可以通过为字段起别名的方式,保证和实体类中的属性名保持一致

b>可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可

**以在查询表中数据时,自动将_类型的字段名转换为驼峰

 <settings>
<!-- 将下划线设置为驼峰-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置延迟加载,默认false(不开启)       -->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--按需加载,默认false(开启)        -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为

userName

2.处理多对一映射

场景模拟:

查询员工信息以及员工所对应的部门信息

员工表:

 部门表:

2.1 级联(嵌套查询)

        用左联将两个表和在一起,然后通过员工实体类的dept类属性.部门实体类的属性来和部门表映射。

 <resultMap id="empAndDeptResultMap" type="emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <result column="dept_id" property="dept.deptId"></result>
        <result column="dept_name" property="dept.deptName"></result>
    </resultMap>
 <select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
        select t_emp.*,t_dept.*
        from t_emp
        left join t_dept
        on t_emp.dept_id=t_dept.dept_id
        where t_emp.emp_id=#{empId}
    </select>

2.2 使用association处理映射关系        

        association标签后要使用javaType表示property属性的类型。(这里的Dept是类型别名,因为设置了别名)

        在配置文件里通过包设置别名。

 <typeAliases>

        <package name="com.xiaoye.pojo"/><!--通过包设置别名,该包下所以类型全有默认类型 -->
    </typeAliases>

使用association

<!--
resultMap:设置自定义映射 
属性: 
id:表示自定义映射的唯一标识 
type:查询的数据要映射的实体类的类型 
子标签: 
id:设置主键的映射关系 
result:设置普通字段的映射关系

association:设置多对一的映射关系 
collection:设置一对多的映射关系 
属性:
property:设置映射关系中实体类中的属性名 
column:设置映射关系中表中的字段名 
-->
<resultMap id="empDeptMap" type="Emp">
    <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
    <association property="dept" javaType="Dept">
        <id column="dep_id" property="depId"></id> 
        <result column="dep_name" property="depName"></result>
    </association>
</resultMap>
<!--Emp getEmpAndDeptByEid(@Param("eid") int eid);--> 
<select id="getEmpAndDeptByEid" resultMap="empDeptMap"> 
    select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = dept.did where emp.eid = #{eid} </select>

2.3 分布查询

1.查询员工id信息

      fetchType="egager”,这是立即加载
      fetchType="lazy“,这是延迟加载

association标签属性
property设置需要处理映射关系的属性的属性名
select设置分步查询的唯一标识
column将查询出的某个字段作为分步查询的下一个查询的sql条件
   fetchType开启了延迟加载后通过该属性设置是否使用延迟加载
Emp getEmpAndDeptByIdStepOne(@Param("empId") Integer empid);
<resultMap id="empAndDeptByStepResultMap" type="emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
<!-- property:设置需要处理映射关系的属性的属性名
     select:设置分步查询的唯一标识
     column:将查询出的某个字段作为分步查询的下一个查询的sql条件
     fetchType:开启了延迟加载后通过该属性设置是否使用延迟加载
      fetchType="egager”,这是立即加载
      fetchType="lazy“,这是延迟加载-->
        <association property="dept" fetchType="eager"
        select="com.xiaoye.mapper.DeptMapper.getEmpAndDeptByStepTwo"
        column="dept_id"
        >
        </association>

    </resultMap>
    <select id="getEmpAndDeptByIdStepOne" resultMap="empAndDeptByStepResultMap">
        select * from t_emp where emp_id=#{empId}
    </select>

2.根据员工部门id查询部门信息

        员工信息获取成功后,根据查询的员工信息的员工部门id作为参数查询部门信息

Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);//通过分步查询员工及对应部门信息
 <select id="getEmpAndDeptByStepTwo" resultType="Dept">
        select * from t_dept where dept_id = #{deptId}
    </select>

3.处理一对多映射

场景模拟:

查询部门信息,并将该部门的员工信息查出。

因为一对多,需要在部门实体类里加一个list集合存放员工信息

3.1 collection标签

        ofType:设置集合类型的属性中存储的数据的类型 

 Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);//查询部门以及部门中的员工

映射文件

<resultMap id="deptAndEmpResultMap" type="dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
<!--ofType:设置集合类型的属性中存储的数据的类型        -->
        <collection property="emps" ofType="Emp">
            <id column="emp_id" property="empId"></id>
            <result column="emp_name" property="empName"></result>
            <result column="age" property="age"></result>
            <result column="gender" property="gender"></result>
        </collection>
    </resultMap>
    <select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
        select * from t_dept
        left join t_emp
        on t_dept.dept_id=t_emp.dept_id
        where t_dept.dept_id=#{deptId}
    </select>

3.2 分步查询

1.查询部门信息

Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);//通过分步查询部门以及部门中员工的信息的第一步
<resultMap id="deptAndEmpResultByStepOne" type="dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <collection property="emps"
                    select="com.xiaoye.mapper.EmpMapper.getDeptAndEmpByStepTwo"
                    column="dept_id">
        </collection>
    </resultMap>
    <select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultByStepOne">
        select * from t_dept where dept_id=#{deptId}
    </select>

2.根据部门id查询员工信息

List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptid);//通过分步查询部门以及部门中员工的信息的第二步
 <select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select * from t_emp where dept_id=#{deptId}
    </select>

分步查询的优点:可以实现延迟加载

但是必须在核心配置文件中设置全局配置信息:

lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载

aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属

性会按需加载

此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和

collection中的fetchType属性设置当前的分步查询是否使用延迟加载, fetchType="lazy(延迟加

载)|eager(立即加载)"

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值