IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> MyBatis--自定义映射resultMap -> 正文阅读

[Java知识库]MyBatis--自定义映射resultMap

新建Mybatis项目,搭建MyBatis框架过程不再赘述,参考前期博客:开始准备工作,此处只给出新内容

准备工作

创两个表,多对一关系(一个部门可以有多个员工),简单添加几条数据,如下:

t_dept表,did主键自增
在这里插入图片描述
t_emp表,eid主键自增
在这里插入图片描述
创建两个pojo类:

Emp.java

package com.mybatis.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ToString
public class Emp {
    private Integer eid;
    private String empName;
    private Integer age;
    private String sex;
    private String email;
}

Dept.java

package com.mybatis.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ToString
public class Dept {
    private Integer did;
    private String deptName;
}

注意:此时,实体类中的部分属性和数据库表中的部分字段命名不一致,如表中字段是采用下划线(emp_name、dept_name),而实体类中采用的是驼峰命名法(empName、deptName)

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

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射

EmpMapper接口

/**
 * 查询所有员工信息
*/
List<Emp> getAllEmp();

EmpMapper映射

<resultMap id="empResultMap" type="Emp">
    <id property="eid" column="eid" />
    <result property="empName" column="emp_name" />
    <result property="age" column="age" />
    <result property="sex" column="sex" />
    <result property="email" column="email" />
</resultMap>
<select id="getAllEmp" resultMap="empResultMap">
	select * from t_emp
</select>

resultMap:设置自定义映射,只在查询有用

  • 属性:

    • id:表示自定义映射的唯一标识
    • type:查询的数据要映射的实体类的类型
  • 子标签:

    • id:设置主键的映射关系
    • result:设置普通字段的映射关系
    • association:设置多对一的映射关系
    • collection:设置一对多的映射关系
    • 属性:
      • property:设置映射关系中实体类中的属性名
      • column:设置映射关系中表中的字段名

测试方法

@Test
public void testGetAllEmp() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    mapper.getAllEmp().forEach(System.out::println);
}

运行结果

在这里插入图片描述

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

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

<select id="getAllEmp" resultType="Emp">
	select eid,emp_name as empName,age,sex,email,did from t_emp
</select

此处为emp_name起别名为empName

b>在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,在查询表中数据时,自动将_类型的字段名转换为驼峰,如下,参考MyBatis核心配置文件

<settings>
	<!--将表中字段的下划线自动转换为驼峰-->
	<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

此处将字段名emp_name自动转换为empName

2、多对一映射处理

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

Emp.java添加一行属性:

private Dept dept;

a>级联方式处理映射关系

EmpMapper接口
/**
* 根据id查询员工所对应的部门信息
*/
Emp getEmpAndDept(@Param("eid") Integer eid);
EmpMapper映射
<resultMap id="empAndDeptResultMapOne" type="Emp">
    <id property="eid" column="eid" />
    <result property="empName" column="emp_name" />
    <result property="age" column="age" />
    <result property="sex" column="sex" />
    <result property="email" column="email" />
    <!--级联属性赋值-->
    <result property="dept.did" column="did" />
    <result property="dept.deptName" column="dept_name" />
</resultMap>
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
	select * from t_emp join t_dept on t_emp.did=t_dept.did where t_emp.eid = #{eid}
</select>
测试方法
@Test
public void testGetEmpAndDept() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    System.out.println(mapper.getEmpAndDept(5));
}
运行结果

在这里插入图片描述

b>使用association处理映射关系

EmpMapper映射
<resultMap id="empAndDeptResultMapTwo" type="Emp">
    <id property="eid" column="eid" />
    <result property="empName" column="emp_name" />
    <result property="age" column="age" />
    <result property="sex" column="sex" />
    <result property="email" column="email" />
    <!--association处理映射-->
    <association property="dept" javaType="Dept">
        <id property="did" column="did" />
        <result property="deptName" column="dept_name" />
    </association>
</resultMap>
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
	select * from t_emp join t_dept on t_emp.did=t_dept.did where t_emp.eid = #{eid}
</select>

association:处理多对一映射关系,属性如下:

  • property:需要处理多对的映射关系的属性名
  • javaType:该属性的类型

运行结果同上

c>分步查询

EmpMapper接口
/**
* 根据id查询员工所对应的部门信息(通过分步查询)
* 分步查询第一步:查询员工信息
*/
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
EmpMapper映射
<resultMap id="empAndDeptByStepResultMap" type="Emp">
    <id property="eid" column="eid" />
    <result property="empName" column="emp_name" />
    <result property="age" column="age" />
    <result property="sex" column="sex" />
    <result property="email" column="email" />
    <association property="dept" select="com.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo" column="did" />
</resultMap>
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
	select * from t_emp where eid = #{eid}
</select>

association属性:

  • select:设置分步查询,查询某个属性的值的sql的标识(即mapper接口的全类名.方法名,在IDEA中使用Ctrl+Alt+Shift+C快捷键可以快速复制)

  • column:将sql以及查询结果中的某个字段设置为分步查询的条件

DeptMapper接口
/**
* 根据id查询员工所对应的部门信息(通过分步查询)
* 分步查询第二步:查询部门信息
*/
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
DeptMapper映射
<select id="getEmpAndDeptByStepTwo" resultType="Dept">
	select * from t_dept where did= #{did}
</select>

在MyBatis核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase为true,_自动转驼峰

测试方法
@Test
public void testGetEmpAndDeptByStep() {
	SqlSession sqlSession = SqlSessionUtil.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	System.out.println(mapper.getEmpAndDeptByStepOne(2));
}
运行结果

在这里插入图片描述

3、一对多映射处理

查询部门信息以及部门中的员工信息

Dept.java添加一行属性:

private List<Emp> emps;

a>使用collection处理映射关系

DeptMapper接口
/**
* 根据部门id查询部门以及部门中的员工信息
*/
Dept getDeptAndEmp(@Param("did") Integer did);
DeptMapper映射
<resultMap id="deptAndEmpResultMap" type="Dept">
    <id property="did" column="did"/>
    <result property="deptName" column="dept_name"/>
    <!--collection处理映射-->
    <collection property="emps" ofType="Emp">
        <id property="eid" column="eid" />
        <result property="empName" column="emp_name" />
        <result property="age" column="age" />
        <result property="sex" column="sex" />
        <result property="email" column="email" /> <!--此处不用设置Emp的did属性-->
    </collection>
</resultMap>
<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
	select * from t_dept join t_emp on t_dept.did=t_emp.did where t_dept.did=#{did}
</select>

collection:处理一对多映射关系,属性如下:

  • ofType:表示该属性所对应的集合中存储数据的类型
测试方法
@Test
public void testGetDeptAndEmp() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
    System.out.println(mapper.getDeptAndEmp(1));
}
运行结果

在这里插入图片描述

Dept(did=1, deptName=A, emps=[
    Emp(eid=1, empName=张飞, age=36, sex=, email=100@163.com, dept=null), 
    Emp(eid=4, empName=孙尚香, age=32, sex=, email=103@sohu.com, dept=null)
])

b>分步查询

DeptMapper接口
/**
* 根据id查询部门以及部门中的员工信息(通过分步查询)
* 分步查询第一步:查询部门信息
*/
Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
DeptMapper映射
<resultMap id="deptAndEmpByStepResultMap" type="Dept">
    <id property="did" column="did"/>
    <result property="deptName" column="dept_name"/>
    <collection property="emps" select="com.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo" column="did"/>
</resultMap>
<select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpByStepResultMap">
	select * from t_dept where did= #{did}
</select>
EmpMapper接口
/**
* 根据id查询部门以及部门中的员工信息(通过分步查询)
* 分步查询第二步:查询员工信息
*/
List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
EmpMapper映射
<select id="getDeptAndEmpByStepTwo" resultType="Emp">
	select * from t_emp where did = #{did}
</select>
测试方法
@Test
public void testGetDeptAndEmpByStep() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
    System.out.println(mapper.getDeptAndEmpByStepOne(1));
}
运行结果

在这里插入图片描述

分步查询的优点:可以实现延迟加载,但是必须在MyBatis核心配置文件中设置全局配置信息:

<settings>
 <!--将表中字段的下划线自动转换为驼峰-->
 <setting name="mapUnderscoreToCamelCase" value="true"/>
 <!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载,默认false-->
 <setting name="lazyLoadingEnabled" value="true"/>
 <!--当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载,默认false-->
 <setting name="aggressiveLazyLoading" value="false"/>
</settings>

此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql;例如只查询部门名称:

System.out.println(mapper.getDeptAndEmpByStepOne(1).getDeptName());
  • 未开启延迟加载

    在这里插入图片描述

  • 开启延迟加载
    在这里插入图片描述

当开启了全局的延迟加载后,可以通过association和collection中的fetchType属性手动控制延迟加载的效果,fetchType=“lazy(延迟加载,默认) | eager(立即加载)”,指定属性后,将在映射中忽略全局配置参数 lazyLoadingEnabled,从而使用该属性的值。

注意:若没有开启全局的延迟加载,fetchType无论设置哪个值,都是立即加载!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:09:53  更:2022-04-09 18:10:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:29:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码