Mybatis的resultMap自定义映射

Mybatis 自定义映射和分布查询:

自定义映射

  • 自定义resultMap,实现高级结果集映射
  • id :用于完成主键值的映射
  • result :用于完成普通列的映射
  • association :一个复杂的类型关联;许多结果将包成这种类型
  • collection : 复杂类型的集

项目结构

数据准备

Amx8Z4.png

AmxZIs.png

项目结构

Amxyod.png

Department

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.hph.mybatis.beans;

import java.util.List;

public class Department {

private Integer id;
private String departmentName ;

private List<Employee> emps ;


public List<Employee> getEmps() {
return emps;
}
public void setEmps(List<Employee> emps) {
this.emps = emps;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
@Override
public String toString() {
return "Department [id=" + id + ", departmentName=" + departmentName + "]";
}
}

Employee

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.hph.mybatis.beans;

public class Employee {

private Integer id;
private String lastName;
private String email;
private Integer gender;

private Department dept;

public void setDept(Department dept) {
this.dept = dept;
}

public Department getDept() {
return dept;
}

public Employee() {
}

public Employee(Integer id, String lastName, String email, Integer gender, Department dept) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
this.dept = dept;
}

public Employee(Integer id, String lastName, String email, Integer gender) {
super();
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
}


public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public Integer getGender() {
return gender;
}

public void setGender(Integer gender) {
this.gender = gender;
}

@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
}

}

EmployeeMapperResultMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.hph.mybatis.dao;

import com.hph.mybatis.beans.Employee;

import java.util.List;

public interface EmployeeMapperResultMap {

public Employee getEmployeeById(Integer id);

public Employee getEmpAndDept(Integer id);

public Employee getEmpAndDeptStep(Integer id);

public List<Employee> getEmpsByDid(Integer did);

}

EmployeeMapperResultMap.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?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.hph.mybatis.dao.EmployeeMapperResultMap">
<!-- 自定义映射
type: 最终结果集封装的类型
<id>: 完成主键列的映射
column: 指定结果集的列名
property:指定对象的属性名
<result>:完成普通列的映射
-->
<select id="getEmployeeById" resultMap="MyEmp">
select id ,last_name, email,gender from tbl_employee where id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Employee" id="MyEmp">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</resultMap>

<!--
需求: 查询员工对象, 并且查询员工所在 的部门信息.
-->
<!-- public Employee getEmpAndDept(Integer id ); -->
<select id="getEmpAndDept" resultMap="myEmpAndDept">
SELECT e.id eid , e.last_name, e.email,e.gender , d.id did , d.dept_name
FROM tbl_employee e , tbl_dept d
WHERE e.d_id = d.id AND e.id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDept">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!-- 级联的方式 -->
<result column="did" property="dept.id"/>
<result column="dept_name" property="dept.departmentName"/>
</resultMap>
<!--
association 使用分步查询:
需求: 查询员工信息并且查询员工所在的部门信息.
1. 先根据员工的id查询员工信息
2. 使用外键 d_id查询部门信息
-->
<!--public Employee getEmpAndDeptStep(Integer id);-->
<select id="getEmpAndDeptStep" resultMap="myEmpAndDeptStep">
select id, last_name, email,gender ,d_id from tbl_employee where id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDeptStep">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!-- 分步查询 -->
<association property="dept"
select="com.hph.mybatis.dao.DepartmentMapperResultMap.getDeptById"
column="{did=d_id}" fetchType="eager">
</association>
</resultMap>
<!-- association 分步查询使用延迟加载/懒加载:
在全局配置文件中加上两个settings设置:
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
-->
<!-- public List<Employee> getEmpsByDid(Integer did ); -->
<select id="getEmpsByDid" resultType="com.hph.mybatis.beans.Employee">
select id,last_name,email,gender from tbl_employee where d_id = #{did}
</select>
</mapper>

TestMapbatisResultMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.hph.mybatis.test;

import com.hph.mybatis.beans.Department;
import com.hph.mybatis.beans.Employee;
import com.hph.mybatis.dao.DepartmentMapperResultMap;
import com.hph.mybatis.dao.EmployeeMapperResultMap;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class TestMapbatisResultMap {

public SqlSessionFactory getsqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}

@Test
public void testResultMap() throws IOException {
SqlSessionFactory ssf = getsqlSessionFactory();
SqlSession session = ssf.openSession();
try {
EmployeeMapperResultMap mapper = session.getMapper(EmployeeMapperResultMap.class);
Employee employee = mapper.getEmployeeById(1001);
System.out.println(employee);
} finally {
session.close();
}
}

@Test
public void testResultMapCascade() throws IOException {
SqlSessionFactory ssf = getsqlSessionFactory();
SqlSession session = ssf.openSession();
try {
EmployeeMapperResultMap mapper = session.getMapper(EmployeeMapperResultMap.class);

Employee employee = mapper.getEmpAndDept(1001);
System.out.println(employee);
System.out.println(employee.getDept());

} finally {
session.close();
}
}

@Test
public void testResultMapAssociation() throws IOException {
SqlSessionFactory ssf = getsqlSessionFactory();
SqlSession session = ssf.openSession();
try {
EmployeeMapperResultMap mapper = session.getMapper(EmployeeMapperResultMap.class);
Employee employee = mapper.getEmpAndDeptStep(1001);
System.out.println(employee);
System.out.println(employee.getDept());
} finally {
session.close();
}
}

@Test
public void testResultMapCollectionStep() throws IOException {
SqlSessionFactory ssf = getsqlSessionFactory();
SqlSession session = ssf.openSession();
try {
DepartmentMapperResultMap mapper = session.getMapper(DepartmentMapperResultMap.class);
Department dept = mapper.getDeptAndEmpsStep(1);
System.out.println(dept.getDepartmentName());
System.out.println(dept.getEmps());
}finally {
session.close();
}
}
}

association

级联

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   <!-- 自定义映射
type: 最终结果集封装的类型
<id>: 完成主键列的映射
column: 指定结果集的列名
property:指定对象的属性名
<result>:完成普通列的映射
-->
<select id="getEmployeeById" resultMap="MyEmp">
select id ,last_name, email,gender from tbl_employee where id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Employee" id="MyEmp">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</resultMap>

testResultMap结果

An2foQ.png

Association

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 <select id="getEmpAndDept" resultMap="myEmpAndDept">
SELECT e.id eid , e.last_name, e.email,e.gender , d.id did , d.dept_name
FROM tbl_employee e , tbl_dept d
WHERE e.d_id = d.id AND e.id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDept">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!-- 级联的方式 -->
<result column="did" property="dept.id"/>
<result column="dept_name" property="dept.departmentName"/>
</resultMap>

getEmpAndDept的结果

AnRPOK.png

分步查询

实际的开发中,对于每个实体类都应该有具体的增删改查方法,也就是DAO层, 因此对于查询员工信息并且将对应的部门信息也查询出来的需求,就可以通过分步的方式完成查询。

① 先通过员工的id查询员工信息

② 再通过查询出来的员工信息中的外键(部门id)查询对应的部门信息.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!--public  Employee getEmpAndDeptStep(Integer id);-->
<select id="getEmpAndDeptStep" resultMap="myEmpAndDeptStep">
select id, last_name, email,gender ,d_id from tbl_employee where id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDeptStep">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!-- 分步查询 -->
<association property="dept"
select="com.hph.mybatis.dao.DepartmentMapperResultMap.getDeptById"
column="{did=d_id}" fetchType="eager">
</association>
</resultMap>
<!-- association 分步查询使用延迟加载/懒加载:
在全局配置文件中加上两个settings设置:
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
-->
<!-- public List<Employee> getEmpsByDid(Integer did ); -->
<select id="getEmpsByDid" resultType="com.hph.mybatis.beans.Employee">
select id,last_name,email,gender from tbl_employee where d_id = #{did}
</select>
延迟加载

在分步查询的基础上,可以使用延迟加载来提升查询的效率,只需要在全局(mybatis-config.xml)的Settings中进行如下的配置:

1
2
3
4
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 设置加载的数据是按需还是全部 -->
<setting name="aggressiveLazyLoading" value="false"/>

collection

POJO中的属性可能会是一个集合对象,我们可以使用联合查询,并以级联属性的方式封装对象.使用collection标签定义对象的封装规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   <select id="getDeptAndEmpsById" resultMap="myDeptAndEmps">
SELECT d.id did ,d.dept_name, e.id eid, e.last_name, e.email,e.gender
FROM tbl_dept d LEFT OUTER JOIN tbl_employee e
ON d.id = e.d_id WHERE d.id = #{id}
</select>
<resultMap type="com.hph.mybatis.beans.Department" id="myDeptAndEmps">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
<!--
collection: 完成集合类型的联合属性的映射
property: 指定联合属性
ofType: 指定集合中元素的类型
-->
<collection property="emps" ofType="com.hph.mybatis.beans.Employee" >
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap>

AnRPOK.png

分步查询

实际的开发中,对于每个实体类都应该有具体的增删改查方法,也就是DAO层, 因此对于查询部门信息并且将对应的所有的员工信息也查询出来的需求,就可以通过分步的方式完成查询。

① 先通过部门的id查询部门信息

② 再通过部门id作为员工的外键查询对应的部门信息.

1
2
3
4
5
6
7
8
9
10
11
12
<select id="getDeptAndEmpsStep" resultMap="myDeptAndEmpsStep">
select id , dept_name from tbl_dept where id = #{id}
</select>

<resultMap id="myDeptAndEmpsStep" type="com.hph.mybatis.beans.Department">
<id column="id" property="id"/>
<result column="dept_name" property="departmentName"/>
<collection property="emps"
select="com.hph.mybatis.dao.EmployeeMapperResultMap.getEmpsByDid"
column="id">
</collection>
</resultMap>

Anh0nP.png

分步查询多列值的传递

如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成Map来进行传递,语法如下: {k1=v1, k2=v2….}

在所调用的查询方,取值时就要参考Map的取值方式,需要严格的按照封装map时所用的key来取值.

column=”{key1=column1,key2=column2}”

fetchType属性

在<association> 和<collection>标签中都可以设置fetchType,指定本次查询是否要使用延迟加载。默认为 fetchType=”lazy” ,如果本次的查询不想使用延迟加载,则可设置为fetchType=”eager”.

fetchType可以灵活的设置查询是否需要使用延迟加载,而不需要因为某个查询不想使用延迟加载将全局的延迟加载设置关闭..

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis 中,ResultMap 是一种将查询结果集映射到 Java 对象中的技术,它可以自定义对查询结果集的映射方式,使得查询结果集中的列与 Java 对象的属性进行映射,从而方便进行数据操作。下面详细介绍一下 Mybatis 中的 ResultMap。 ### ResultMap定义 ResultMap定义可以在 Mapper.xml 文件中使用 <resultMap> 标签进行定义,示例代码如下: ```xml <resultMap id="userMap" type="com.example.User"> <id property="id" column="user_id" /> <result property="username" column="user_name"/> <result property="age" column="user_age"/> </resultMap> ``` 其中: - `id`:ResultMap 的唯一标识符; - `type`:映射结果集的 Java 类型; - `id` 和 `result`:用来映射结果集中的列和 Java 对象的属性,其中 `id` 用来映射主键,`property` 表示 Java 对象的属性名,`column` 表示查询结果集中的列名。 ### ResultMap 的使用 在 Mapper.xml 文件中的 SQL 语句中使用 ResultMap,示例代码如下: ```xml <select id="selectUser" resultMap="userMap"> select user_id, user_name, user_age from user where user_id = #{id} </select> ``` 其中,`resultMap` 属性指定了使用的 ResultMap 的 id。 ### ResultMap 的继承 Mybatis 还支持 ResultMap 的继承,可以通过 extends 属性来实现。示例代码如下: ```xml <resultMap id="userMap" type="com.example.User"> <id property="id" column="user_id" /> <result property="username" column="user_name"/> <result property="age" column="user_age"/> </resultMap> <resultMap id="userMapWithAddress" type="com.example.User" extends="userMap"> <result property="address" column="user_address"/> </resultMap> ``` 在上面的示例中,`userMapWithAddress` 继承了 `userMap`,因此可以使用 `userMap` 中定义映射关系,同时还可以添加自己的映射关系。 ### ResultMap 的自动映射 Mybatis 还支持自动映射,它会根据查询结果集中的列名自动匹配 Java 对象中的属性名,从而省略 ResultMap定义。可以使用 `autoMapping="true"` 来启用自动映射。示例代码如下: ```xml <select id="selectUser" resultType="com.example.User" autoMapping="true"> select user_id, user_name, user_age from user where user_id = #{id} </select> ``` 在上述代码中,`resultType` 属性指定了映射结果集的 Java 类型,而 `autoMapping` 属性启用了自动映射。 ### 总结 - MybatisResultMap 是将查询结果集映射到 Java 对象中的技术; - ResultMap 可以在 Mapper.xml 文件中定义,并在 SQL 语句中使用; - ResultMap 可以继承,可以自动映射

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值