8、自定义映射resultMap

文章目录

  • 8、自定义映射resultMap
    • 8.1、环境
    • 8.2、使用SQL或全局配置
    • 8.3、resultMap处理字段和属性的映射关系
    • 8.4、多对一映射处理
      • 8.4.1 映射关系
      • 8.4.2 实体类
      • 8.4.3 级联方式处理映射关系
      • 8.4.4 使用association处理映射关系
      • 8.4.5 分步查询
    • 8.5、延迟加载
    • 8.6、一对多映射处理
      • 8.6.1 collection
      • 8.6.2 分布查询


【尚硅谷】SSM框架全套教程-讲师:杨博超

失败,是正因你在距成功一步之遥的时候停住了脚步。

8、自定义映射resultMap

8.1、环境

t_emp表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_emp
-- ----------------------------
DROP TABLE IF EXISTS `t_emp`;
CREATE TABLE `t_emp`  (
  `emp_id` int NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `age` int NULL DEFAULT NULL,
  `gender` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `dept_id` int NULL DEFAULT NULL,
  PRIMARY KEY (`emp_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_emp
-- ----------------------------
INSERT INTO `t_emp` VALUES (1, '张三', 20, '男', 1);
INSERT INTO `t_emp` VALUES (2, '李四', 22, '男', 2);
INSERT INTO `t_emp` VALUES (3, '王五', 23, '男', 3);
INSERT INTO `t_emp` VALUES (4, '赵六', 26, '男', 1);

SET FOREIGN_KEY_CHECKS = 1;

t_dept表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_dept
-- ----------------------------
DROP TABLE IF EXISTS `t_dept`;
CREATE TABLE `t_dept`  (
  `dept_id` int NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`dept_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_dept
-- ----------------------------
INSERT INTO `t_dept` VALUES (1, 'A');
INSERT INTO `t_dept` VALUES (2, 'B');
INSERT INTO `t_dept` VALUES (3, 'C');
INSERT INTO `t_dept` VALUES (4, 'D');

SET FOREIGN_KEY_CHECKS = 1;

Emp.java

public class Emp {
    private Integer empId;
    private String empName;
    private Integer age;
    private String gender;
}

Dept.java

public class Dept {
    private Integer deptId;
    private String deptName;
}

8.2、使用SQL或全局配置

  • 方式一:可以通过为字段起别名的方式,保证和实体类中的属性名保持一致。
  • 若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰),可以使用方式二。
  • 方式二:在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰。
  • 例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。

EmpMapper.java

/**
 * 根据员工Id查询员工
 *
 * @param empId
 * @return
 */
Emp getEmpByEmpId(@Param("empId") int empId);

EmpMapper.xml


<select id="getEmpByEmpId" resultType="Emp">
    
    select * from t_emp where emp_id = #{empId}
select>

测试

@Test
public void testGetEmpByEmpId() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.getEmpByEmpId(1);
    System.out.println(emp);
}

方式二核心文件配置

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
settings>

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

  • 若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
  • resultMap:设置自定义映射
  • 属性:
  • id:表示自定义映射的唯一标识
  • type:查询的数据要映射的实体类的类型
  • 子标签:
  • id:设置主键的映射关系
  • result:设置普通字段的映射关系
  • association:设置多对一的映射关系
  • collection:设置一对多的映射关系
  • 属性:
  • property:设置映射关系中实体类中的属性名
  • column:设置映射关系中表中的字段名

EmpMapper.xml

<resultMap id="empResultMap" type="Emp">
    <id property="empId" column="emp_id">id>
    <result property="empName" column="emp_name">result>
    <result property="age" column="age">result>
    <result property="gender" column="gender">result>
resultMap>

<select id="getEmpByEmpId" resultType="Emp">
    select * from t_emp where emp_id = #{empId}
select>

8.4、多对一映射处理

8.4.1 映射关系

多个员工对应一个部门
多对一:对应的是一个对象

8.4.2 实体类

Student.java

public class Emp {
    private Integer empId;
    private String empName;
    private Integer age;
    private String gender;
    private Dept dept;
}

Dept.java

public class Dept {
    private Integer deptId;
    private String deptName;
}

8.4.3 级联方式处理映射关系

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

EmpMapper.java

/**
 * 获取员工以及所有对应部门的信息
 *
 * @param empId
 * @return
 */
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);

EmpMapper.xml

<resultMap id="empAndDept" type="Emp">
    <id property="empId" column="emp_id">id>
    <result property="empName" column="emp_name">result>
    <result property="age" column="age">result>
    <result property="gender" column="gender">result>
    <result property="dept.deptId" column="dept_id">result>
    <result property="dept.deptName" column="dept_name">result>
resultMap>

<select id="getEmpAndDeptByEmpId" resultMap="empAndDept">
    select te.emp_id, te.emp_name, te.age, te.gender, td.dept_id, td.dept_name
    from t_emp te
             left join t_dept td on te.dept_id = td.dept_id
    where te.emp_id = #{empId};
select>

测试

@Test
public void testGetEmpAndDeptByEmpId() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.getEmpAndDeptByEmpId(1);
    System.out.println(emp);
}

8.4.4 使用association处理映射关系

  • association:处理多对一映射关系(处理实体类类型的属性)
  • property:设置需要处理映射关系的属性的属性名
  • javaType:设置要处理的属性的类型

EmpMapper.xml

<resultMap id="empAndDeptResult" type="Emp">
    <id property="empName" column="emp_name">id>
    <result property="empName" column="emp_name">result>
    <result property="age" column="age">result>
    <result property="gender" column="gender">result>
    <association property="dept" javaType="Dept">
        <id property="deptId" column="dept_Id">id>
        <result property="deptName" column="dept_name">result>
    association>
resultMap>

<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResult">
    select te.emp_id, te.emp_name, te.age, te.gender, td.dept_id, td.dept_name
    from t_emp te
             left join t_dept td on te.dept_id = td.dept_id
    where te.emp_id = #{empId};
select>

测试

@Test
public void testGetEmpAndDeptByEmpId() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.getEmpAndDeptByEmpId(1);
    System.out.println(emp);
}

8.4.5 分步查询

property:设置需要处理映射关系的属性的属性名
select:设置分布查询的SQL的唯一表示,(namespace.sqlId)
column:将查询出的某个字段作为分步查询的sql的条件

①查询员工信息
EmpMapper.java

/**
 * 获取员工以及所有对应部门的信息
 *
 * @param empId
 * @return
 */
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);

EmpMapper.xml

<resultMap id="empAndDeptByStepResultMap" type="Emp">
    <id property="empId" column="emp_id">id>
    <result property="empName" column="emp_name">result>
    <result property="age" column="age">result>
    <result property="gender" column="gender">result>
    <association property="dept"
                 select="pers.tianyu.mapper.DeptMapper.getEmpAndDeptByStepTow"
                 column="dept_id">

    association>
resultMap>

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

②根据员工所对应的部门id查询部门信息
DeptMapper.java

/**
 * 查询部门信息
 *
 * @param deptId
 * @return
 */
Dept getEmpAndDeptByStepTow(@Param("deptId") Integer deptId);

DeptMapper.xml


<select id="getEmpAndDeptByStepTow" resultType="Dept">
    select *
    from t_dept
    where dept_id = #{deptId};
select>

测试

@Test
public void testGetEmpAndDeptByStepOne() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.getEmpAndDeptByStepOne(1);
    System.out.println(emp);
}

8.5、延迟加载

  • 分步查询的优点:可以实现延迟加载
  • 但是必须在核心配置文件中设置全局配置信息:
  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
  • aggressiveLazyLoading:按需加载的全局开关,当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和
  • collection中的fetchType属性设置当前的分步查询是否使用延迟加载, fetchType=“lazy(延迟加载)|eager(立即加载)”

mybatis-config.xml


<setting name="lazyLoadingEnabled" value="true"/>

<setting name="aggressiveLazyLoading" value="false"/>

EmpMapper.xml

在resultMap标签下association标签写设置fetchType=“eager”,可以单个查询不使用延迟加载。

8.6、一对多映射处理

一对多:对应的是一个集合

8.6.1 collection

  • collection:处理一对多的映射关系(处理集合类型的属性)
  • ofType:设置collection标签所处理的集合属性中存储数据的类型

Dept.java

public class Dept {
    private Integer deptId;
    private String deptName;
    private List<Emp> emp;
}

DeptMapper.xml

<resultMap id="deptEmpMap" type="Dept">
    <id property="deptId" column="dept_id">id>
    <result property="deptName" column="dept_name">result>
    <collection property="emp" ofType="Emp">
        <id property="empId" column="emp_id">id>
        <result property="empName" column="emp_name">result>
        <result property="age" column="age">result>
        <result property="gender" column="gender">result>
    collection>
resultMap>


<select id="getDeptEmpByDid" resultMap="deptEmpMap">
    select *
    from t_dept td
             left join t_emp te on td.dept_id = te.dept_id
    where td.dept_id = #{deptId}
select>

8.6.2 分布查询

①查询部门信息
DeptMapper.java

/**
 * 分布查询部门和部门中的员工
 *
 * @param deptId
 * @return
 */
Dept getDeptByStep(@Param("deptId") Integer deptId);

DeptMapper.xml

<resultMap id="deptEmpStep" type="Dept">
    <id property="deptId" column="dept_id">id>
    <result property="deptName" column="dept_name">result>
    <collection property="emp"
                select="pers.tianyu.mapper.EmpMapper.getEmpListByDeptId"
                column="dept_id">
    collection>
resultMap>

<select id="getDeptByStep" resultMap="deptEmpStep">
    select *
    from t_dept
    where dept_id = #{deptId};
select>

②根据部门id查询部门中的所有员工
EmpMapper.java

/**
 * 根据部门id查询员工信息
 *
 * @param deptId
 * @return
 */
List<Emp> getEmpListByDeptId(@Param("deptId") Integer deptId);

EmpMapper.xml


<select id="getEmpListByDeptId" resultType="Emp">
    select *
    from t_emp
    where dept_id = #{deptId};
select>

你可能感兴趣的:(MyBatis,java,mybatis)