MyBatis resultMap 元素
resultMap元素
resultMap元素是MyBatis中最重要最强大的元素。它的作用是告诉MyBatis将从结果集中取出的数据转换成开发者所需要的对象。下面是最简单的映射语句示例:
<select id="selectUser" resultType="map">
SELECT * FROM TB_USER
</select>
selectUser的<select.../>
元素执行一条查询语句,查询TB_USER表的所有数据。resultType="map"
表示返回的数据是一个Map 集合(使用列名作为key,列值作为value)。
虽然数据被封装成Map集合返回,但是Map集合并不能很好地描述一个领域模型。我们更加建议使用JavaBeans或POJOs (Plain Old Java Objects,普通Java 对象) 来作为领域模型描述数据。例如:
<select id="selectUser" resultType="cn.mybatis.domain.User">
SELECT * FROM TB_USER
</select>
默认情况下,MyBatis 会将查询到的数据的列和需要返回的对象(User)的属性逐一进行匹配赋值,但是如果查询到的数据的列和需要返回的对象(User)的属性不一致,则MyBatis就不会自动赋值了,这时可以使用resultMap 进行处理。
<resultMap id="userResultMap" type="cn.mybatis.domain.User >
<id property="id" column="user_id" />
<result property="name" column-"user_name"/>
<result property="sex" column="user_sex"/>
<result property="age" column="user_age"/>
</resultMap>
<!-- resultMap-"userResultMap"表示引用上面的resultMap进行数据库表和返回类型对象的映射-->
<select id="selectUser" resultMap="userResultMap">
SELECT * FROM TB_USER
</select>
上面使用了一个新的元素<resultMap.../>,该元素常用属性如下:
id属性:resultMap 的唯一标示符。
type属性:resultMap 实际返回的类型。
上面使用了<resultMap.../>
的两个子元素id和result。
id:表示数据库表的主键,其中,column 属性表示数据库表的列名,property 表示数据库列映射到返回类型的属性。
result:表示数据库表的普通列,其中,column属性表示数据库表的列名,property表示数据库列映射到返回类型的属性。
在实际项目开发中,还有更加复杂的情况,例如执行的是一个多表查询语句,而返回的对象关联到另一个对象,此时简单的映射已经无法解决问题,必须使用<resultMap.../>
元素来完成关联映射。
现在我们创建两个表TB_CLAZZ和TB_STUDENT,并分别插入几条测试数据。
CREATE TABLE TB _CLAZZ(
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR (18)
)
INSERT INTO TB_CLAZZ(CODE) VALUES('201801');
INSERT INTO TB_CLAZZ (CODE) VALUES('201802');
CREATE TABLE TB_STUDENT(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(18),
sex CHAR(3),
age INT,
clazz_ id INT,
FOREIGN KEY (clazz_id) REFERENCES TB_CLAZZ(id)
)
INSERT INTO TB_STUDENT(NAME,sex,age,clazz_id) VALUES('jack',' 男',22,1) ;
INSERT INTO TB_STUDENT(NAME,sex,age,clazz_id) VALUES('rose','女',18,1) ;
INSERT INTO TB_STUDENT(NAME,sex,age,clazz_id) VALUES('tom','男',25,2) ;
INSERT INTO TB_STUDENT(NAME,sex,age,clazz_id) VALUES ('mary','女',20,2) ;
以上SQL语句插入了两个班级记录和4个学生记录,两个学生分配在1班,两个学生分配在2班。需要指出的是,TB_STUDENT 表中的clazz_id 列作为外键引用到TB_CLAZZ 表的id 列,表示学生对应的班级。
接下来我们要做的是查询出所有的学生信息,同时关联查询出学生对应的班级信息。创建一个Clazz 对象和Student 对象并分别映射TB_CLAZZ 表和TB_STUDENT 表。
public class Clazz {
private Integer id;
private string code;
// 省賂set和get方法.....
}
public class Student {
private Integer id;
private String name;
private String sex;
private Integer age;
// 关联的Clazz对象
private Clazz clazz ;
// 省略set和get方法.....
}
需要注意的是,Student 中的属性Clazz是一个对象,该对象包括Clazz的id和code。这是现代开发中最常用的对象关联方式。
UserMpper.xml文件如下所示:
<!-- 映射学生对象的resultMap-->
<resultMap id="studentResultMap" type="cn.mybatis.domain.Student">
<id property="id" column="id" />
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
< !-- 关联映射
<association property="clazz" column="clazz_id"
javaType="cn.mybatis.domain.Clazz"
select="selectClazzWithId" />
</resultMap>
<!-- 根据班级id查询班级-->
<select id="selectClazzWithId" resultType="cn.mybatis.domain.Clazz">
SELECT * FROM TB_CLASS where id = #{id}
</select>
<!-- 查询所有学生信息-->
< select id="selectStudent" resultMap="studentResultMap" >
SELECT * FROM TB_STUDENT
</select>
上面的映射相对之前复杂了一些,具体解释如下:
(1)首先执行id为selectStudent的<select.../>
元素,查询所有的学生数据,此时返回的不是简单的Student对象,因为Student 对象中还包含了Clazz对象,所以使用resultMap去映射返回类型。
(2)id为studentResultMap的<resultMap.../>
元素返回类型为cn.mybatis.domain.Student。其中,id、name.sex 和age都是简单的属性映射,而查询的班级id列clazz_id 则使用了关联映射<association../>
。
<association.../>元素的解释如下:
column:表示数据库表的列名。
property:表示返回类型Student的属性名clazz。
javaType:表示该属性对应的类型名称,本示例是一个Clazz类型。
select:表示执行一条查询语句,将查询到的数据封装到property所代表的类型对象当中。上面的selectClazzWithId就是执行一条SQL语句,将学生的clazz_id作为参数查询对应的班级信息。