使用 resultMap 实现高级结果集映射
resultMap 的基本配置项
属性
id 属性:resultMap 的唯一标识,此 id 值用于 select 元素 resultMap 属性的引用。
type 属性:表示该 resultMap 的映射结果类型(通常是 Java 实体类)。
子节点
id 子节点:一般对应数据库中该行的主键 id,设置此项可以提升 MyBatis 性能。
result 子节点:映射到 JavaBean 的某个 “简单类型” 属性,如基础数据类型、包装类等。
子节点属性
column 属性:表示从数据库中查询的字段名或别名。
property 属性:表示查询出来的字段对应的值赋给实体对象的哪个属性。
说明:子节点 id 和 result 均可实现最基本的结果集映射,将列映射到简单数据类型的属性。这两者唯一不同的是:在比较对象实例时 id 将作为结果集的标识属性。这有助于提高总体性能,特别是应用缓存和嵌套结果映射的时候。而若要实现高级结果映射,就需要学习下面两个配置项: association 和 collection。
ssociation
association:映射到 JavaBean 的某个 “复杂类型” 属性,比如 JavaBean 类,即 JavaBean 内部嵌套一个复杂数据类型(JavaBean)属性,这种情况就属于复杂类型的关联。但是需要注意: association 仅处理一对一的关联关系。
ssociation 的属性
javaType 属性:完整 Java 类名或者别名。若映射到一个 JavaBean,则 MyBatis 通常会自行检测到其类型;若映射到一个 HashMap ,则应该明确指定 javaType,来确保所需行为。
property 属性:映射数据库列的实体对象的属性。
ssociation 的子元素
id 子元素:一般对应数据库中该行的主键 id,设置此项可以提升 MyBatis 性能。
result 子元素:
◆ property 属性:映射数据库列的实体对象的属性。
◆ column 属性:数据库列名或别名。
说明
(1)在做结果映射的过程中,需要注意:要确保所有的列名都是唯一且无歧义的。
(2)id 子元素在嵌套结果映射中扮演了非常重要的角色,应该指定一个或者多个属性来唯一标识这个结果集。实际上,即便没有指定 id, MyBatis 也会工作,但是会导致严重的性能开销,所以最好选择尽量少的属性来唯一标识结果,主键或者联合主键均可。
案例:根据用户角色 id 获取该角色下的用户列表
(1)修改 User 类,增加角色属性 (private Role role) ,并增加相应的 getter 和 setter 方法。 private Role role; //复杂类型:用户角色 public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
} (2)在 UserMapper.java 接口里增加根据角色 id 获取用户列表的方法。 /**
* 根据用户角色 id 获取该角色下的用户列表
* @param roleId 用户角色 id
* @return
*/
public List<User> getUserListByRoleId(@Param("uRole")int roleId); (3)在 UserMapper.xml 里增加 id 为 getUserListByRoleId 的查询语句,该查询语句返回类型为 resultMap,并且外部引用的 resultMap 的类型为 User。
说明:由于 User 对象内嵌 JavaBean 对象(role),因此需要使用 association 来实现结果映射。 <!--根据用户角色 id 获取该角色下的用户列表 -->
<select id="getUserListByRoleId" resultMap="userRoleResult"
parameterType="int">
SELECT u.* , r.id AS r_id , r.`roleCode` , r.`roleName`
FROM `smbms_user` AS u,`smbms_role` AS r
WHERE u.`userRole`=#{uRole} AND u.`userRole`=r.`id`
</select> <resultMap type="user" id="userRoleResult">
<id property="id" column="id" />
<result property="userCode" column="userCode" />
<result property="userName" column="userName" />
<result property="userRole" column="userRole" /> <association property="role" javaType="role">
<id property="id" column="r_id" />
<result property="roleCode" column="roleCode" />
<result property="roleName" column="roleName" />
</association>
</resultMap> (4)单元测试类使用 Junit 测试 @Test //测试根据用户角色 id 获取该角色下的用户列表
public void testGetUserListByRoleId(){
List<User> userList=new ArrayList<User>();
userList=session.getMapper(UserMapper.class).getUserListByRoleId(2); //打印 用户角色 id 为 2 的用户有几个
System.out.println("userList 的长度:"+userList.size());
//使用 resultMap 实现复杂类型关联
for (User user : userList) {
System.out.println("User:"+user.getUserName()+
"---Role:"+user.getRole().getId()+"---"+user.getRole().getRoleCode()+"---"+user.getRole().getRoleName());
}
}
复用 association 的结果映射
association 提供了的另一个属性: resultMap 通过这个属性可以扩展一个 resultMap 来进行联合映射,这样就可以使 role 结果映射重复使用。特别适合 association 的结果映射比较多的情况,当然,若不需要重用,也可按照上面代码的写法,直接嵌套这个联合结果映射,根据具体业务而定。
//使用 resultMap 属性完成 association 的 role 映射结果的复用,修改 UserMapper.xml ,association 子节点上增加 resultMap 属性来引用外部的 resultMap。 <!--根据用户角色 id 获取该角色下的用户列表 -->
<select id="getUserListByRoleId" resultMap="userRoleResult"
parameterType="int">
SELECT u.* , r.id AS r_id , r.`roleCode` , r.`roleName`
FROM `smbms_user` AS u,`smbms_role` AS r
WHERE u.`userRole`=#{uRole} AND u.`userRole`=r.`id`
</select> <resultMap type="user" id="userRoleResult">
<id property="id" column="id" />
<result property="userCode" column="userCode" />
<result property="userName" column="userName" />
<result property="userRole" column="userRole" /> <association property="role" javaType="role" resultMap="roleResult" />
</resultMap> <resultMap type="role" id="roleResult">
<id property="id" column="r_id"/>
<result property="roleCode" column="roleCode"/>
<result property="roleName" column="roleName"/>
</resultMap>
collection
collection 元素的作用和 association 元素的作用差不多一样,事实上,它们非常类似,也是映射到 JavaBean 的某个 “复杂类型” 属性,只不过这个属性是一个集合列表,即 JavaBean 内部嵌套一个复杂数据类型(集合)属性。和使用 association 元素一样,我付使用嵌套查询,或者从连接中嵌套结果集。
collection 的属性
ofType 属性:完整 Java 类名或者别名,即集合所包含的类型。
property 属性:映射数据库列的实体对象的属性。
collection 的子元素
id 子元素:一般对应数据库中该行的主键 id,设置此项可以提升 MyBatis 性能。
result 子元素:
◆ property 属性:映射数据库列的实体对象的属性。
◆ column 属性:数据库列名或别名。
案例:获取指定用户的相关信息和地址列表
(1)在 User 实体类中,增加地址列表属性 private List<Address> addressList ,并增加相应的 getter 和 setter 方法。User 对象内部嵌套了一个复杂数据类型的属性,addressList。 private List<Address> addressList; //用户地址列表 public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
} (2)在 UserMapper.java 接口中增加根据用户 id 获取用户信息以及地址列表的方法。 /**
* 根据用户 id 获取指定用户的相关信息和地址列表
* @param userId 用户 id
* @return
*/
public List<User> getAddressListByUserId(@Param("id")int userId); (3)在 UserMapper.xml 中增加 id 为 getAddressListByUserId 的查询语句,该 select 查询语句返回类型为 resultMap ,并且引用外部的 resultMap 的类型为 User。由于 User 对象内嵌集合对象(addressList) ,因此需要使用 collection 来实现结果映射。 <!--根据用户 id 获取指定用户的相关信息和地址列表-->
<select id="getAddressListByUserId" resultMap="userAddressResult" parameterType="int">
SELECT u.*,a.`id` AS a_id ,a.`contact`,a.`addressDesc`,a.`postCode`,a.`tel`
FROM `smbms_user` u ,`smbms_address` a
WHERE u.`id`=a.`userId` AND u.`id`=#{id}
</select> <resultMap type="user" id="userAddressResult">
<id property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/> <collection property="addressList" ofType="address">
<id property="id" column="a_id"/>
<result property="postCode" column="postCode"/>
<result property="tel" column="tel"/>
<result property="contact" column="contact"/>
<result property="addressDesc" column="addressDesc"/>
</collection>
</resultMap> (4)单元测试类使用 Junit 测试 @Test //测试根据用户 id 获取指定用户的相关信息和地址列表
public void testGetAddressListByUserId() {
List<User> userList = new ArrayList<User>();
userList = session.getMapper(UserMapper.class).getAddressListByUserId(1); for (User user : userList) {
System.out.println("userList(include:addresslist) =====> userCode: " + user.getUserCode() + ", userName: "
+ user.getUserName());
for (Address address : user.getAddressList()) {
System.out.println("address ----> id: " + address.getId() + ", contact: " + address.getContact()
+ ", addressDesc: " + address.getAddressDesc() + ", tel: " + address.getTel() + ", postCode: "
+ address.getPostCode());
}
}
}
复用 collection 的结果映射
提取相应代码到一个 resultMap 中,给 collection 增加 resultMap 属性进行外部引用即可。
<!--根据用户 id 获取指定用户的相关信息和地址列表-->
<select id="getAddressListByUserId" resultMap="userAddressResult" parameterType="int">
SELECT u.*,a.`id` AS a_id ,a.`contact`,a.`addressDesc`,a.`postCode`,a.`tel`
FROM `smbms_user` u ,`smbms_address` a
WHERE u.`id`=a.`userId` AND u.`id`=#{id}
</select> <resultMap type="user" id="userAddressResult">
<id property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/> <collection property="addressList" ofType="address" resultMap="addressResult"/>
</resultMap> <resultMap type="address" id="addressResult">
<id property="id" column="a_id"/>
<result property="postCode" column="postCode"/>
<result property="tel" column="tel"/>
<result property="contact" column="contact"/>
<result property="addressDesc" column="addressDesc"/>
</resultMap>
使用 resultMap 实现高级结果集映射的更多相关文章
- 使用resultMap实现高级结果映射
使用resultMap实现高级结果映射 resultMap的属性: 1.属性 id:resultMap的唯一标识.type:resulMap的映射结果类型(一般为Java实体类).2.子节点 id:一 ...
- oracle使用resultMap实现高级结果映射
resultMap的属性: 1.属性 id:resultMap的唯一标识.type:resulMap的映射结果类型(一般为Java实体类).2.子节点 id:一般对应数据库的主键 id,设置此项可以提 ...
- mybatis框架-使用resultMap实现高级结果映射,collection属性的使用
需求:获取指定用户的用户信息和地址列表 修改user实体类 添加集合的引用. /** * 根绝用户id,获取该角色下的地址信息 * @param userID * @return */ public ...
- mybatis框架-使用resultMap实现高级结果映射,association属性
需求:查询数特定角色下的所有用户列表 首先需要在在User类中引用Role类,因为引用了复杂的数据类型,所以要使用association属性进行映射,其实起主要作用的还是resultMap属性. /* ...
- ResultMap(还没细看)
前言 MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转换的手段了,而res ...
- JavaEE高级-MyBatis学习笔记
一.MyBatis简介 - MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架. - MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. - My ...
- resultMap自定义映射(多对一)
自定义resultMap,处理复杂的表关系,实现高级结果集映射 1) id :用于完成主键值的映射 2) result :用于完成普通列的映射 3) association :一个复杂的类型关联;许多 ...
- Mybatis-利用resultMap 输出复杂pojo
个:复杂的sql语句查询的数据集的字段和 pojo的字段不相同,需要用到resultMap做一个对应. ---------------- mybatis中使用resultMap完成高级输出结果映射. ...
- Mybatis中输出映射resultType与resultMap的区别
Mybatis中输出映射resultType与resultMap的区别 (原文地址:http://blog.csdn.net/acmman/article/details/46509375) 一.re ...
随机推荐
- SGU 145
节点不可重复经过的K短路问题. 思路:二分路径长度,深搜小于等于路径长度的路径数.可以利用可重复点K短路问题中的A*函数进行剪枝. 尝试另一种解法:把可重复点K短路A*直接搬过来,堆中的每个元素额外记 ...
- ubuntu 12.04.5 LTS版本 更新 source.list
更新后一定要:apt-get update # # deb cdrom:[Ubuntu-Server LTS _Precise Pangolin_ - Release amd64 (20140806. ...
- 不温不火WindowsPhone
最近在考虑是否转其他平台,如iOS或者Android或者javascript等. 已经以Windows Phone 开发作为工作就一年了(也不算是真正的Windows Phone开发吧,仅仅是开发高德 ...
- 9. Ext基础1 -- Ext中 getDom、get、getCmp的区别
转自:https://blog.csdn.net/huobing123456789/article/details/7982061 要学习及应用好Ext框架,必须需要理解Html DOM.Ext El ...
- 在visual studio code和visual studio中编写TypeScript文件自动生成JavaScript文件
注:此处的自动生成都为保存ts文件时自动生成js文件 VS CODE 只需要在TypeScript的终端控制台中输入如下命令即可,并注意需要将其中的*换成对应的文件名,此处的*似乎不能作为通用匹配. ...
- centos 重装docker
docker应该是root用户来使用,因为他连接了底层!!!以下操作默认是root用户来操作的 停止所有正在运行的容器: docker stop $(docker ps -a -q) 删除所有的容器c ...
- git 详细部署及其应用
第1章 版本控制系统 自动生成备份.随时回滚.知道改动的地方. 1.1 svn和git的区别 1.1.1 svn 集中式的版本控制系统,只有一个中央数据仓库,如果中央数据库仓库挂了或者不可访问,所有的 ...
- [Qt Creator 快速入门] 第3章 窗口部件
从这一章开始正式接触Qt的窗口部件.在第2章曾看到 Qt Creator 提供的默认基类只有 QMainWindow.QWidget 和 QDialog 这3种.QMainWindow 是带有菜单栏和 ...
- [译]Cookies Without Chocolate Chips
Cookies Without Chocolate Chips In the HTTP sense, a cookie is a name with an associated value. A se ...
- 重新学习Java——对象和类(二)
上一节回归了如何以面向对象的思想去使用一些Java中的公共类,也设计了一些自己的类并介绍了设计类的基本方法和技巧,这一节我们将继续回顾这些内容,并争取从中获得新的体验和感受. 1. 静态域与静态方法 ...