Mybatis resultMap标签继承、复用、嵌套
记录演示 Mybatis
中 resultMap
标签继承、复用(包括跨文件)以及多层嵌套的使用方法,
继承
: 继承已存在的resultMap
标签进行扩展复用
: 跨mapper文件引用现存的resultMap
标签嵌套
: 多层嵌套的JavaBean与resultMap
映射方法
一、定义表与实体类
- 表
创建三个表 group
member
score
score
与 member
一对一,通过 score.id
关联
group
与 member
一对多,通过 group.id
关联
create table `score` (
`id` int comment '主键',
`math` float comment '数学成绩',
`history` float comment '历史成绩',
primary key (`id`)
)
create table `member` (
`id` int comment '主键',
`name` varchar comment '姓名',
`group_id` int comment '所属组group表id',
`score_id` int comment '成绩Score表id',
primary key (`id`)
)
create table `group` (
`id` int comment '主键',
`name` varchar comment '组名',
primary key (`id`)
)
- 实体类
创建三个实体类 Group
Member
Score
Score
类的对象是 Member
类的成员变量
Member
类的对象集合是 Group
类的成员变量
/** 成绩类 */
public class Score {
private Integer id;
/** 数学成绩 */
private Float math;
/** 历史成绩 */
private Float hitory;
...getter And setter...
}
/** 成员类 */
public class Member {
private Integer id;
/** 姓名 */
private String name;
/** 分数对象 */
private Score score;
...getter And setter...
}
/** 组类 */
public class Group {
private Integer id;
/** 组名 */
private String groupName;
/** 成员 */
private List<Member> members;
...getter And setter...
}
- 定义与表映射的
resultMap
在 BeanMapper.xml
定义最基本的与数据库表字段映射的 resultMap
标签
<?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.example.BeanMapper">
<!-- Score实体类映射 -->
<resultMap id="scoreMap" type="com.example.Score">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="math" jdbcType="FLOAT" property="math" />
<result column="history" jdbcType="FLOAT" property="history" />
</resultMap>
<!-- Member实体类映射 -->
<resultMap id="memberMap" type="com.example.Member">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>
<!-- Group实体类映射 -->
<resultMap id="groupMap" type="com.example.Group">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="groupName" />
</resultMap>
</mapper>
二、继承、复用、嵌套
创建 DemoMapper.xml
,演示标签的继承、复用、嵌套
复用现存标签时若位于相同mapper文件可直接使用 resultMap
的 id
属性引用,跨文件时需要指定 namespace
属性才可正常引用
extends
: 继承,可继承其他resultMap
并加以扩展association
: 复用现存的resultMap
,适用于对应的属性为单JavaBean
时,使用javaType
指定Java类型collection
: 复用现存的resultMap
,适用于对应的属性为JavaBean集合
时,使用ofType
指定Java类型columnPrefix
: 只将该属性指定前缀的属性赋值给当前resultMap
,存在多层嵌套时每进入一层就会将本层前缀截取掉。- 如下面的mapper文件中,外层的
fullMemberMap
前缀为member_
,经本次筛选member_score_id
->score_id
,
内层的scoreMap
前缀为score_
,经本次筛选score_id
->id
,最终被赋值给Score.id
所以只有形如member_score_id
的字段才会最终进入scoreMap
的取值范围中
- 如下面的mapper文件中,外层的
- 若是不复用只是单纯嵌套,则可以直接将三个类写在一个
resultMap
标签内实现
<?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.example.DemoMapper">
<!-- extends: 继承 -->
<resultMap id="fullMemberMap" extends="com.example.BeanMapper.memberMap" type="com.example.Member">
<!-- association: 复用已存在的resultMap,单JavaBean属性时使用
使用javaType属性指定JavaBean的类型
跨文件引用需指定namespace -->
<!-- columnPrefix: 只从 score_ 开头的字段为当前resultMap取值 -->
<association property="score" resultMap="com.example.BeanMapper.scoreMap" javaType="com.example.Score" columnPrefix="score_" />
</resultMap>
<resultMap id="fullGroupMap" extends="com.example.BeanMapper.groupMap" type="com.example.Group">
<!-- collection: 复用已存在的resultMap,JavaBean集合属性时使用
使用ofType属性指定JavaBean的类型
同文件引用无需指定namespace -->
<!-- columnPrefix: 只从 member_ 开头的字段为当前resultMap取值
进入fullMemberMap内嵌套的scoreMap时前缀 member_ 会被去除,即 member_score_id 字段才能被scoreMap正确接收 -->
<collection property="members" ofType="com.example.Member" resultMap="fullMemberMap" columnPrefix="member_"/>
</resultMap>
<!-- 直接引用最终的resultMap,并根据columnPrefix属性设置的前缀为各个字段指定不同的别名 -->
<select id="selectGroupById" parameterType="java.lang.Integer" resultMap="fullGroupMap">
select g.id, g.name,
m.id member_id, m.name member_name,
s.id member_score_id, s.math member_score_math, s.history member_score_history
from `group` g
left join `member` m on m.group_id = g.id
left join `score` s on s.id = m.score_id
where g.id = #{id,jdbcType=INTEGER}
</select>
</mapper>