MyBatis(三)(1)

简介: MyBatis(三)(1)

6. 自定义映射resultMap

6.1 代码结构

SqlSessionUtils.java、jdbc.properties、log4j.xml延用上面章节的。

6.1.1 mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="jdbc.properties"/>
    <!--设置MyBatis的全局配置-->
    <settings>
        <!--将_自动映射为驼峰,emp_name:empName-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.atguigu.mybatis.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.atguigu.mybatis.mapper"/>
    </mappers>
</configuration>

6.1.2 pojo

Dept

部门信息

package com.atguigu.mybatis.pojo;
public class Dept {
    private Integer did;
    private String deptName;
    //省略get、set
}
Emp

员工信息

package com.atguigu.mybatis.pojo;
public class Emp {
    private Integer eid;
    private String empName;
    private Integer age;
    private String sex;
    private String email;
    //员工所属部门
    private Dept dept;
}

6.1.3 mapper

EmpMapper
package com.atguigu.mybatis.mapper;
import com.atguigu.mybatis.pojo.Emp;
public interface EmpMapper {
    /**
     * 查询所有的员工信息
     */
    List<Emp> getAllEmp();
    /**
     * 查询员工以及员工所对应的部门信息
     */
    Emp getEmpAndDept(@Param("eid") Integer eid);
    /**
     * 通过分步查询查询员工以及员工所对应的部门信息
     * 分步查询第一步:查询员工信息
     */
    Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
    /**
     * 通过分步查询查询部门以及部门中所有的员工信息
     * 分步查询第二步:根据did查询员工信息
     */
    List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
}
DeptMapper
package com.atguigu.mybatis.mapper;
import com.atguigu.mybatis.pojo.Dept;
public interface DeptMapper {
    /**
     * 通过分步查询查询员工以及员工所对应的部门信息
     * 分步查询第二步:通过did查询员工所对应的部门
     */
    Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
    /**
     * 获取部门以及部门中所有的员工信息
     */
    Dept getDeptAndEmp(@Param("did") Integer did);
    /**
     * 通过分步查询查询部门以及部门中所有的员工信息
     * 分步查询第一步:查询部门信息
     */
    Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
}

6.2 映射文件和测试编写

EmpMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.mapper.EmpMapper">
    <!--
        resultMap:设置自定义映射关系
        id:唯一标识,不能重复
        type:设置映射关系中的实体类类型
        子标签:
        id:设置主键的映射关系
        result:设置普通字段的映射关系
        属性:
        property:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
        column:设置映射关系中的字段名,必须是sql语句查询出的字段名
    -->
    <resultMap id="empResultMap" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
    </resultMap>
    <!--List<Emp> getAllEmp();-->
    <select id="getAllEmp" resultMap="empResultMap">
        select * from t_emp
    </select>
    <!--处理多对一映射关系方式一:级联属性赋值-->
    <resultMap id="empAndDeptResultMapOne" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <result property="dept.did" column="did"></result>
        <result property="dept.deptName" column="dept_name"></result>
    </resultMap>
    <!--处理多对一映射关系方式二:association-->
    <resultMap id="empAndDeptResultMapTwo" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <!--
            association:处理多对一的映射关系
            property:需要处理多对的映射关系的属性名
            javaType:该属性的类型
        -->
        <association property="dept" javaType="Dept">
            <id property="did" column="did"></id>
            <result property="deptName" column="dept_name"></result>
        </association>
    </resultMap>
    <!--Emp getEmpAndDept(@Param("eid") Integer eid);-->
    <select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
        select * from t_emp left join t_dept on t_emp.did = t_dept .did where t_emp.eid = #{eid}
    </select>
    <resultMap id="empAndDeptByStepResultMap" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <!--
            select:设置分步查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
            column:设置分布查询的条件
            fetchType:当开启了全局的延迟加载之后,可通过此属性手动控制延迟加载的效果
            fetchType="lazy|eager":lazy表示延迟加载,eager表示立即加载
        -->
        <association property="dept"
                     select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                     column="did"
                     fetchType="eager"></association>
    </resultMap>
    <!--Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);-->
    <select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
        select * from t_emp where eid = #{eid}
    </select>
    <select id="getAllEmpOld" resultType="Emp">
        <!--select eid,emp_name empName,age,sex,email from t_emp-->
        select * from t_emp
    </select>
    <!--List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);-->
    <select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select * from t_emp where did = #{did}
    </select>
</mapper>

ResultMapTest.java

package com.atguigu.mybatis.test;
import com.atguigu.mybatis.mapper.DeptMapper;
import com.atguigu.mybatis.mapper.EmpMapper;
import com.atguigu.mybatis.pojo.Dept;
import com.atguigu.mybatis.pojo.Emp;
import com.atguigu.mybatis.utils.SqlSessionUtils;
public class ResultMapTest {
    /**
     * 解决字段名和属性名不一致的情况:
     * a>为字段起别名,保持和属性名的一致
     * b>设置全局配置,将_自动映射为驼峰
     * <setting name="mapUnderscoreToCamelCase" value="true"/>
     * c>通过resultMap设置自定义的映射关系
     * <resultMap id="empResultMap" type="Emp">
     *     <id property="eid" column="eid"></id>
     *     <result property="empName" column="emp_name"></result>
     *     <result property="age" column="age"></result>
     *     <result property="sex" column="sex"></result>
     *     <result property="email" column="email"></result>
     * </resultMap>
     *
     * 处理多对一的映射关系:
     * a>级联属性赋值
     * b>association
     * c>分步查询
     *
     * 处理一对多的映射关系
     * a>collection
     * b>分步查询
     */
    @Test
    public void testGetEmpAndDeptByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDeptByStepOne(3);
        System.out.println(emp.getEmpName());
        System.out.println("+++++++++++++++++++++++++++++++++++++");
        System.out.println(emp.getDept());
    }
    @Test
    public void testGetEmpAndDept(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDept(3);
        System.out.println(emp);
    }
    @Test
    public void testGetAllEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> list = mapper.getAllEmp();
        list.forEach(emp -> System.out.println(emp));
    }
    @Test
    public void testGetDeptAndEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = mapper.getDeptAndEmp(1);
        System.out.println(dept);
    }
    @Test
    public void testGetDeptAndEmpByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = mapper.getDeptAndEmpByStepOne(1);
        System.out.println(dept.getDeptName());
    }
}

6.2.1 resultMap处理字段和属性的映射关系

resultMap:设置自定义映射

id:表示自定义映射的唯一标识,不能重复

type:查询的数据要映射的实体类的类型

id:设置主键的映射关系

result:设置普通字段的映射关系

property:设置映射关系中实体类中的属性名

column:设置映射关系中中的字段名

EmpMapper.xml

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射,即使字段名和属性名一致的属性也要映射,也就是全部属性都要列出来

<!--resultMap:设置自定义映射
id:设置唯一标识,不能重复
type:设置实体类类型
-->
<resultMap id="empResultMap" type="Emp">
  <!--id:设置主键映射关系
    property:设置实体类的属性名
    column:设置表中对应的字段-->
    <id property="eid" column="eid"></id>
  <result property="empName" column="emp_name"></result>
  <result property="age" column="age"></result>
  <result property="sex" column="sex"></result>
  <result property="email" column="email"></result>
</resultMap>
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultMap="empResultMap">
  select * from t_emp
</select>
@Test
  //获取所有的员工
    public void testGetAllEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> list = mapper.getAllEmp();
        list.forEach(emp -> System.out.println(emp));
    }

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)。此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系

  1. 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="Emp">
  select eid,emp_name empName,age,sex,email from t_emp
</select>
  1. 可以在MyBatis的核心配置文件中的setting标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。
<settings>
 <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

6.2.2 多对一映射处理

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

public class Emp {  
  private Integer eid;  
  private String empName;  
  private Integer age;  
  private String sex;  
  private String email;  
    
    //加一行这个    员工所属的部门  多个员工对应一个部门
  private Dept dept;
  //...构造器、get、set方法等
}
6.2.2.1 级联方式处理映射关系
<resultMap id="empAndDeptResultMapOne" type="Emp">
  <id property="eid" column="eid"></id>
  <result property="empName" column="emp_name"></result>
  <result property="age" column="age"></result>
  <result property="sex" column="sex"></result>
  <result property="email" column="email"></result>
    
  <result property="dept.did" column="did"></result>
  <result property="dept.deptName" column="dept_name"></result>
</resultMap>
<!--Emp getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
  select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>
@Test
  //获取员工信息  和这个员工所属的部门
    public void testGetEmpAndDept(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDept(3);
        System.out.println(emp);
    }
6.2.2.2 使用association处理映射关系
  • association:处理多对一的映射关系
  • property:需要处理多对的映射关系的属性名
  • javaType:该属性的类型
<resultMap id="empAndDeptResultMapTwo" type="Emp">
  <id property="eid" column="eid"></id>
  <result property="empName" column="emp_name"></result>
  <result property="age" column="age"></result>
  <result property="sex" column="sex"></result>
  <result property="email" column="email"></result>
  
    <association property="dept" javaType="Dept">
    <id property="did" column="did"></id>
    <result property="deptName" column="dept_name"></result>
  </association>
</resultMap>
<!--Emp getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
  select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>
6.2.2.3 分步查询

1. 查询员工信息

  • select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
  • column:设置分步查询的条件
//EmpMapper里的方法
/**
 * 通过分步查询,员工及所对应的部门信息
 * 分步查询第一步:查询员工信息
 * @param  
 * @return com.atguigu.mybatis.pojo.Emp
 */
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
<resultMap id="empAndDeptByStepResultMap" type="Emp">
  <id property="eid" column="eid"></id>
  <result property="empName" column="emp_name"></result>
  <result property="age" column="age"></result>
  <result property="sex" column="sex"></result>
  <result property="email" column="email"></result>
    
    <!--
        select:设置分步查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
        column:设置分布查询的条件
        fetchType:当开启了全局的延迟加载之后,可通过此属性手动控制延迟加载的效果
        fetchType="lazy|eager":lazy表示延迟加载,eager表示立即加载
    --> 
    <association property="dept"
         select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
         column="did"></association>
</resultMap>
<!--Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
  select * from t_emp where eid = #{eid}
</select>

2. 查询部门信息

//DeptMapper里的方法
/**
 * 通过分步查询,员工及所对应的部门信息
 * 分步查询第二步:通过did查询员工对应的部门信息
 * @param
 * @return com.atguigu.mybatis.pojo.Emp
 */
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
<!--此处的resultMap仅是处理字段和属性的映射关系-->
<resultMap id="EmpAndDeptByStepTwoResultMap" type="Dept">
  <id property="did" column="did"></id>
  <result property="deptName" column="dept_name"></result>
</resultMap>
<!--Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);-->
<select id="getEmpAndDeptByStepTwo" resultMap="EmpAndDeptByStepTwoResultMap">
  select * from t_dept where did = #{did}
</select>

MyBatis(三)(2)+https://developer.aliyun.com/article/1556671

目录
打赏
0
1
1
0
17
分享
相关文章
基于遗传优化的Sugeno型模糊控制器设计matlab仿真
本课题基于遗传优化的Sugeno型模糊控制器设计,利用MATLAB2022a进行仿真。通过遗传算法优化模糊控制器的隶属函数参数,提升控制效果。系统原理结合了模糊逻辑与进化计算,旨在增强系统的稳定性、响应速度和鲁棒性。核心程序实现了遗传算法的选择、交叉、变异等步骤,优化Sugeno型模糊系统的参数,适用于工业控制领域。
MyBatis中对象映射关联之association使用实践
MyBatis中对象映射关联之association使用实践
705 1
mybatis映射关系(1-1 1-n n-n)
Mybatis 中的关系映射包括一对一、一对多和多对多。一对一映射可以通过ResultMap定义属性与字段的对应。一对多示例中,User类包含List&lt;Role&gt;,在User的mapper.xml中使用&lt;collection&gt;标签。多对一的情况,如Author与Blog,Blog的ResultMap中使用&lt;association&gt;来映射Author属性。多对多时,如部门与用户,通常需要中间表,并在双方实体中通过&lt;collection&gt;引用中间类,如UserForDept,来维护关系。
如何在Java中进行网络编程:Socket与NIO
如何在Java中进行网络编程:Socket与NIO
PowerMock的静态方法与私有方法怎么测试?
**PowerMock**是Java单元测试中的增强工具,扩展了Mockito,支持模拟静态方法、构造函数、私有方法和final类,促进更高测试覆盖率。它用于隔离依赖,测试静态方法和私有方法。常见问题包括配置复杂性、过度使用、忽略真实行为模拟和最佳实践。解决方案包括遵循官方文档、谨慎使用、精确模拟和测试后清理。示例展示了如何模拟静态方法,通过添加PowerMock依赖和使用`@RunWith(PowerMockRunner.class)`、`@PrepareForTest`注解,以及`PowerMockito.mockStatic()`进行静态方法模拟。
329 0
Flink CDC+Kafka 加速业务实时化
阿里巴巴开发工程师,Apache Flink Committer 任庆盛,在 9 月 24 日 Apache Flink Meetup 的分享。
Flink CDC+Kafka 加速业务实时化
Java IO流终极指南:从InputStream/OutputStream到Reader/Writer的全面解读
【6月更文挑战第26天】Java IO流涵盖字节流(InputStream/OutputStream)和字符流(Reader/Writer),前者处理二进制数据,后者专司文本。例如,FileInputStream/FileOutputStream用于文件的字节级读写,而FileReader/FileWriter处理字符级文本。Buffered流提供缓冲功能,提升效率。选择合适的流类取决于数据类型和性能需求。
210 0
VsCode 配置 C/C++ 开发环境,真的很简单!!!
VsCode 配置 C/C++ 开发环境,真的很简单!!!
493 0
一文彻底搞懂Mybatis系列(十二)之MyBatis多对一映射延迟加载(association和lazyLoadingEnabled)
一文彻底搞懂Mybatis系列(十二)之MyBatis多对一映射延迟加载(association和lazyLoadingEnabled)
185 0
【Mybatis用法】Mybatis 高级结果映射,ResultMap Association,mybatis的一对多,多对一,以及多对多的配置和使用
【Mybatis用法】Mybatis 高级结果映射,ResultMap Association,mybatis的一对多,多对一,以及多对多的配置和使用
318 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问