概述
resultMap
resultMap:自定义结果集映射规则,自定义某个JavaBean的封装规则。
id:唯一id,方便引用。
type:自定义规则的Java类。
具体其他属性详细信息和配置代码如下:
<resultMap id="MyEmp" type="com.test.mybatis.bean.Employee">
<!--
id:指定主键列的封装规则(主键也可以使用result来定义)
column:指定哪一列
property:指定对应的javaBean属性
-->
<id column="id" property="id"></id>
<!--
result:定义普通列封装规则
-->
<result column="last_name" property="lastName"></result>
<!--其他不指定的列会自动封装:我们只要写resultMap,就尽量把所有的列都写上-->
<result column="email" property="email"></result>
<result column="gender" property="gender"></result>
</resultMap>
<select id="getEmpById" resultMap="MyEmp">
select * from tbl_employee where id = #{id}
</select>
如果出现如下场景:查询Employee的同时查询员工对应的部门,规定一个员工有与之对应的部门信息(员工信息表中会保存部门信息的主键作为外键);数据库如下设置如下(SQL server数据库):
员工表tbl_employee:
CREATE TABLE [dbo].[tbl_employee] (
[id] int NOT NULL IDENTITY(1,1) ,
[last_name] varchar(255) COLLATE Chinese_PRC_CI_AS NULL ,
[gender] char(1) COLLATE Chinese_PRC_CI_AS NULL ,
[email] varchar(255) COLLATE Chinese_PRC_CI_AS NULL ,
[d_id] int NULL ,
CONSTRAINT [PK__tbl_empl__3213E83F8C42E8B6] PRIMARY KEY ([id]),
CONSTRAINT [FK__tbl_employ__d_id__1273C1CD] FOREIGN KEY ([d_id]) REFERENCES [dbo].[tbl_dept] ([id]) ON DELETE NO ACTION ON UPDATE CASCADE
)
ON [PRIMARY]
GO
DBCC CHECKIDENT(N'[dbo].[tbl_employee]', RESEED, 6)
GO
其中数据如下图:
部门表tbl_dept:
CREATE TABLE [dbo].[tbl_dept] (
[id] int NOT NULL IDENTITY(1,1) ,
[dept_name] varchar(255) COLLATE Chinese_PRC_CI_AS NULL ,
CONSTRAINT [PK__tbl_dept__3213E83F4110434E] PRIMARY KEY ([id])
)
ON [PRIMARY]
GO
DBCC CHECKIDENT(N'[dbo].[tbl_dept]', RESEED, 2)
GO
其中数据如下图:
下面我们有两种方法来实现:
联合查询:级联属性封装结果集
分步查询:第一步,按照员工id查询出员工id;第二步,根据员工id信息中的d_id值去部门表中查询出部门信息;第三步,将查询出的部门设置到员工中。
具体实现如下:
我们首先编写实体类Employee和Department:
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
private Department dept;
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + ''' +
", email='" + email + ''' +
", gender='" + gender + ''' +
'}';
}
public Employee() {
}
public Employee(Integer id, String lastName, String email, String gender) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
}
}
public class Department {
private Integer id;
private String departmentName;
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 + ''' +
'}';
}
public Department() {
}
public Department(Integer id, String departmentName) {
this.id = id;
this.departmentName = departmentName;
}
}
然后我们编写相关接口和方法:
public interface DepartmentMapper {
public Department getDeptById(Integer id);
}
public interface EmployeeMapperPlus {
public Employee getEmpAndDept(Integer id);
public Employee getEmpByIdStep(Integer id);
}
然后我们编写相关配置文件:
全局配置文件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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=mybatis"/>
<property name="username" value="sa"/>
<property name="password" value="sa123456"/>
</dataSource>
</environment>
</environments>
<!-- 将我们写好的sql映射文件注册到全局配置文件中 -->
<mappers>
<mapper resource="EmployeeMapperPlus.xml"/>
<mapper resource="DepartmentMapper.xml"/>
</mappers>
</configuration>
然后编写DepartmentMapper.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.test.mybatis.dao.DepartmentMapper">
<select id="getDeptById" resultType="com.test.mybatis.bean.Department">
select id,dept_name departmentName from tbl_dept where id =#{id};
</select>
</mapper>
然后编写EmployeeMapperPlus.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.test.mybatis.dao.EmployeeMapperPlus">
<!--
联合查询:级联属性封装结果集
-->
<resultMap id="MyEmpAndDept" type="com.test.mybatis.bean.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<result column="did" property="dept.id"/>
<result column="dept_name" property="dept.departmentName"/>
</resultMap>
<!--
使用association定义关联的单个对象的封装规则;
-->
<resultMap id="MyEmpAndDept2" type="com.test.mybatis.bean.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<!--
可以指定联合的JavaBean对象
property="dept":指定哪个属性是联合的对象
javaType:指定这个属性对象的类型,不能省略
-->
<association property="dept" javaType="com.test.mybatis.bean.Department">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
</association>
</resultMap>
<select id="getEmpAndDept" resultMap="MyEmpAndDept2">
SELECT e.id id, e.last_name last_name, e.gender gender, e.d_id d_id, d.id did, d.dept_name dept_name
FROM tbl_employee e,tbl_dept d WHERE e.d_id = d.id AND e.id =
#{id}
</select>
<!--
使用association进行分步查询
-->
<resultMap id="MyEmpByStep" type="com.test.mybatis.bean.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!--
使用association定义关联对象的封装规则;
select:表明当前属性是调用select指定的方法查询出的
column:指定将哪一列的值传给这个方法
流程:使用select指定的方法(使用column指定的这列的参数的值),并封装给property指定的属性
-->
<association property="dept" select="com.test.mybatis.dao.DepartmentMapper.getDeptById"
column="d_id">
</association>
</resultMap>
<select id="getEmpByIdStep" resultMap="MyEmpByStep">
select * from tbl_employee where id = #{id}
</select>
</mapper>
然后我们进行测试MyBatisTest2:
public class MyBatisTest2 {
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test05() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try{
EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
//Employee empById = mapper.getEmpById(1);
//System.out.println(empById);
Employee empAndDept = mapper.getEmpByIdStep(5);
System.out.println(empAndDept);
System.out.println(empAndDept.getDept());
}finally {
openSession.close();
}
}
}
其中注释掉的是级联查询的测试。项目结构如下:
分布查询测试结果如下:
我们查询出了我们想要的结果。
分步查询的好处:
可以延迟加载,也叫懒加载。我们每次查询Employee对象的时候,都将一起查询出来部门信息,我们可以在需要的时候再去查询。我们需要在mybatis-config.xml加入两个配置:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 默认值为false。
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载。默认值为false。
这两个属性配置好之后,我们修改测试类,只输出System.out.println(empAndDept.getEmail());,再次测试:
跟上面的测试结果图对比,这次我们只查询了员工信息,并没有查询部门信息。
除了association,我们还需要了解一下collection。嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则。
ofType:指定集合里面元素的类型。
fetchType="lazy":表示使用延迟加载,lazy:延迟;eager:立即加载。
还有一个discriminator鉴别器:mybatis可以使用discriminator判断某列的值,根据某列的值改变封装行为。
javaType:列值对应的Java类型
column:指定判定的类名
如果查询部门的时候将部门对应的所有员工信息也查询出来,我们就可以用collection标签来实现:
<resultMap id="MyDept" type="com.test.mybatis.bean.Department">
<id column="did" property="id"></id>
<result column="dept_name" property="departmentName"></result>
<collection property="emps" ofType="com.test.mybatis.bean.Employee" fetchType="lazy">
<!--定义这个集合中元素的封装规则-->
<id column="eid" property="id"></id>
<result column="last_name" property="lastName"></result>
<result column="email" property="email"></result>
<result column="gender" property="gender"></result>
<!--鉴别器-->
<discriminator javaType="string" column="gender">
<!--此处的resultType不能少,也可以是resultMap-->
<case value="0" resultType="com.test.mybatis.bean.Employee">
<!--编写相关信息-->
</case>
<case value="1" resultType="com.test.mybatis.bean.Employee">
<!--编写相关信息-->
</case>
</discriminator>
</collection>
</resultMap>
<select id="getDeptByIdPlus" resultMap="MyDept">
SELECT d.id did, d.dept_name dept_name,e.id eid,e.last_name last_name,e.email email,e.gender gender
from tbl_dept d LEFT JOIN tbl_employee e on d.id = e.d_id WHERE d.id=#{id};
</select>
还需要补充的一点是,在做分步查询的时候,column表示将某一列的值传给这个方法,如何我们要将多列的值传递给某方法,我们将多列的值封装map传递:
column="{key1=column1,key2=column2}
注:此文章为【尚硅谷_MyBatis_入门到进阶】学习笔记。原视频中是Java代码,连接的数据库是Mysql,开发工具为eclipse。因个人学习需求,此文章为Java代码,但是数据库是SQL server,开发工具用的是IDEA。
最后
以上就是喜悦皮皮虾为你收集整理的mybatis学习笔记之——mybatis的Mapper XML文件中resultMap属性的全部内容,希望文章能够帮你解决mybatis学习笔记之——mybatis的Mapper XML文件中resultMap属性所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复