resultMap-学习

resultMap是MyBatis的自定义结果映射规则,使用频繁。

resultMap基础使用

映射文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--resultMap:自定义某个javaBean的封装规则
type:自定义规则的Java类型
id:唯一id方便引用
-->
<resultMap type="entity.Ban" id="resultMap1">
<!--指定主键列的封装规则
id定义主键会底层有优化;
column:指定哪一列,数据库中的列,在查询语句中使用别名,这里也可以写别名
property:指定对应的javaBean属性
-->
<id column="id" property="id"/>
<!-- 定义普通列封装规则 -->
<!-- 其他不指定的列会自动封装 -->
<result column="ban" property="ban"/>
</resultMap>
<!-- resultMap:自定义结果集映射规则; -->
<!-- public Ban getClassInfo(Integer id); 接口方法-->
<select id="getClassInfo" resultMap="resultMap1">
select * from Student_class where id=#{id}
</select>

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}

@Test
public void testResultMap1() throws IOException {
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession openSession = sessionFactory.openSession();
try {
BanDao classDao = openSession.getMapper(BanDao.class);
Ban classInfo = classDao.getClassInfo(2);
System.out.println(classInfo);
}finally {
openSession.close();
}
}

resultMap单个对象联合查询

场景一:

    查询user的同时查询学生对应的班级

    user.userclass=Student_class.id

    一个学生有与之对应的班级信息;

    id name sex userclass || id ban

映射文件

在resultMap中使用使用association定义关联的单个对象的封装规则。

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
<!--
联合查询:级联属性封装结果集
-->
<!--
使用association定义关联的单个对象的封装规则;
-->
<resultMap type="entity.Student" id="resultMap2">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<result column="userclass" property="Userclass"/>
<!-- association可以指定联合的javaBean对象
property="ban":指定哪个属性是联合的对象
javaType:指定这个属性对象的类型[不能省略]
-->
<association property="ban" javaType="entity.Ban">
<id column="id" property="id"/>
<result column="ban" property="ban"/>
</association>
</resultMap>

<!-- public Student getResultStudent(Integer id); 接口方法-->
<select id="getResultStudent" resultMap="resultMap2">
SELECT distinct u.id id,u.name name,u.sex sex,u.userclass userclass,s.id id,s.ban ban
FROM user u,student_class s
WHERE u.userclass=s.id AND u.id=#{id}
</select>

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testResultMap2() throws IOException {
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession openSession = sessionFactory.openSession();
try {
BanDao banDao = openSession.getMapper(BanDao.class);
Student student = banDao.getResultStudent(1);
Ban ban = student.getBan();
System.out.println(student);
System.out.println(ban);
}finally {
openSession.close();
}
}

resultMap联合分步查询

使用association进行分步查询。

映射文件

使用分步查询需要新建一个班级的映射文件。
学生信息映射文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- 使用association进行分步查询:
1、先按照学生id查询学生信息
2、根据查询学生信息中的userclass值去班级表查出班级信息
3、班级设置到学生中;
-->

<resultMap type="entity.Student" id="resultMapstep">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<result column="userclass" property="Userclass"/>
<!-- association定义关联对象的封装规则
select:表明当前属性是调用select指定的方法查出的结果
column:指定将哪一列的值传给这个方法

流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
这里调用的班级信息映射文件中的方法,调用方式为映射文件命名空间+方法id。
property="ban" 这是实体类中的属性名
-->
<association property="ban"
select="Dao.BanMapper.getBanbyId" column="userclass">
</association>
</resultMap>

班级信息映射文件

1
2
3
4
5
6
7
8
9
10
?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="Dao.BanMapper">
<!-- public Ban getBanbyId(Integer id); 新的接口类的接口方法-->
<select id="getBanbyId" resultType="entity.Ban">
select id,ban from student_class where id=#{id}
</select>
</mapper>

测试

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void testResultMapStep() throws IOException {
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession openSession = sessionFactory.openSession();
try {
BanDao banDao = openSession.getMapper(BanDao.class);
Student banIdstep = banDao.getBanIdstep(3);
System.out.println(banIdstep);
}finally {
openSession.close();
}
}

resultMap集合对象关联查询

场景二:

   查询班级的时候将班级对应的所有学生信息也查询出来:注释在BanMapper.xml中

BanMapper.xml(班级信息映射文件)

嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则。

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
<!-- public class Ban {

private Integer id;
private String ban;
private List<Student> emp; 集合
-->
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 -->
<resultMap type="entity.Ban" id="ListResultMap">
<!--这里主键列名是用的是别名,详情看下方SQL语句-->
<id column="IDB" property="id"/>
<result column="ban" property="ban"/>
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面元素的类型
-->
<collection property="emp" ofType="entity.Student">
<!-- 定义这个集合中元素的封装规则 -->
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<result column="userclass" property="Userclass"/>
</collection>
</resultMap>

<!-- public Ban getbanIDList(Integer id); 接口方法-->
<select id="getbanIDList" resultMap="ListResultMap">
<!-- 在使用级联查询的时候,如果主表和副表的主键都是相同的在MyBatis中查询结果只会出现一条
需要启用别名,使用了别名需要在collection处也更改列的名称
-->
SELECT s.id IDB,s.ban,u.id,u.name,u.sex,u.userclass
FROM student_class s
LEFT JOIN user u
ON s.id=u.userclass
WHERE s.id=#{id}
</select>

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testResultMapcollection() throws IOException {
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession openSession = sessionFactory.openSession();
try {
BanMapper mapper = openSession.getMapper(BanMapper.class);
Ban list = mapper.getbanIDList(1);
List<Student> list2 = list.getList();
System.out.println(list);
System.out.println(list2);
}finally {
openSession.close();
}
}

resultMap集合对象关联分步查询

使用collection进行分步查询。

映射文件

班级映射文件

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
?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="Dao.BanMapper">
<resultMap type="entity.Ban" id="ListResultMapStep">
<id column="id" property="id"/>
<result column="ban" property="ban"/>
<!--跟association使用方式差不多-->
<collection property="emp"
select="Dao.BanDao.getStudent" column="id">
</collection>
</resultMap>
<!-- public Ban getbanIDListStep(Integer id); 接口方法-->
<select id="getbanIDListStep" resultMap="ListResultMapStep">
select * from student_class where id=#{id}
</select>
</mapper>

学生信息映射文件
```Xml
<!-- public List<Student> getStudent(Integer id); 接口方法-->
<select id="getStudent" resultType="entity.Student">
select * from user where userclass=#{id}
</select>

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testResultMapcollectionStep() throws IOException {
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession openSession = sessionFactory.openSession();
try {
BanMapper mapper = openSession.getMapper(BanMapper.class);
Ban listStep = mapper.getbanIDListStep(1);
//这里获取需关闭懒加载,否者获取不到list信息,全局配置文件中设置
List<Student> list = listStep.getList();
System.out.println(listStep);
System.out.println(list);
}finally {
openSession.close();
}
}

总结

在使用分步查询的时候需要一个实体类拥有一个方法接口和相对应的映射文件,最重要的是一定要把映射文件注册到全局配置文件中。

原创技术分享,您的支持将鼓励我继续创作
0%