MyBatis/Ibatis框架,resultMap标签中association子标签中resultMap属性使用。
本文主要讲解 SysUserMapper.xml文件中,resultMap标签下的 association子标签调用 SysRoleMapper.xml文件时的一些框架缺陷。 SysUserMapper.xml文件中,resultMap标签下的 association子标签调用 SysRoleMapper.xml文件中的resultMap标签时,被调用的 SysRoleMapper.xml的resultMap标签的id值必须为: BaseResultMap 。
下面是一个小例子,请详细观看 SysUserMapper.xml文件、SysRoleMapper.xml文件中的相关配置。
项目目录图片
1、 SysUser.java、SysRole.java 实体类如下,此处省略 get()、set()函数
SysUser.java实体类:
package com.moon.mybatis.pojo;
import java.util.Arrays;
import java.util.Date;
public class SysUser {
/**
* 用户ID
*
* id
*/
private Long id;
/**
* 用户名
*
* user_name
*/
private String userName;
/**
* 密码
*
* user_password
*/
private String userPassword;
/**
* 邮箱
*
* user_email
*/
private String userEmail;
/**
* 创建时间
*
* create_time
*/
private Date createTime;
/**
* 简介
*
* user_info
*/
private String userInfo;
/**
* 头像
*
* head_img
*/
private byte[] headImg;
/**
* 用户角色
*/
private SysRole sysRole;
/**
* 重写 toString()函数
*/
@Override
public String toString() {
return "SysUser [id=" + id + ", userName=" + userName + ", userPassword=" + userPassword + ", userEmail="
+ userEmail + ", createTime=" + createTime + ", userInfo=" + userInfo + ", headImg="
+ Arrays.toString(headImg) + ", sysRole=" + sysRole + "]";
}
/**
* 全参构造函数,包含sysRole属性.
*
* @param id
* @param userName
* @param userPassword
* @param userEmail
* @param createTime
* @param userInfo
* @param headImg
* @param sysRole
*/
public SysUser(Long id, String userName, String userPassword, String userEmail, Date createTime, String userInfo,
byte[] headImg, SysRole sysRole) {
super();
this.id = id;
this.userName = userName;
this.userPassword = userPassword;
this.userEmail = userEmail;
this.createTime = createTime;
this.userInfo = userInfo;
this.headImg = headImg;
this.sysRole = sysRole;
}
/**
* 全参构造函数,不包含sysRole属性.
*
* @param id
* @param userName
* @param userPassword
* @param userEmail
* @param createTime
* @param userInfo
* @param headImg
*/
public SysUser(Long id, String userName, String userPassword, String userEmail, Date createTime, String userInfo,
byte[] headImg) {
super();
this.id = id;
this.userName = userName;
this.userPassword = userPassword;
this.userEmail = userEmail;
this.createTime = createTime;
this.userInfo = userInfo;
this.headImg = headImg;
}
/**
* 无参构造函数
*/
public SysUser() {
super();
}
// 此处省略 get()、 set() 函数
}
SysRole.java实体类:
package com.moon.mybatis.pojo;
import java.util.Date;
public class SysRole {
/**
* 角色ID
*
* id
*/
private Long id;
/**
* 角色名
*
* role_name
*/
private String roleName;
/**
* 有效标志
*
* enabled
*/
private Integer enabled;
/**
* 创建人
*
* create_by
*/
private Long createBy;
/**
* 创建时间
*
* create_time
*/
private Date createTime;
/**
* 重写 toString() 函数
*/
@Override
public String toString() {
return "SysRole [id=" + id + ", roleName=" + roleName + ", enabled=" + enabled + ", createBy=" + createBy
+ ", createTime=" + createTime + "]";
}
/**
* 全参构造函数
*
* @param id
* @param roleName
* @param enabled
* @param createBy
* @param createTime
*/
public SysRole(Long id, String roleName, Integer enabled, Long createBy, Date createTime) {
super();
this.id = id;
this.roleName = roleName;
this.enabled = enabled;
this.createBy = createBy;
this.createTime = createTime;
}
/**
* 无参构造函数
*/
public SysRole() {
super();
}
// 此处省略 get()、set()函数
}
2、 SysUserMapper.java文件内容如下:
package com.moon.mybatis.mapper;
import com.moon.mybatis.pojo.SysUser;
public interface SysUserMapper {
/**
* 一对一映射,使用resultMap的association标签配置一对一映射,association标签的resultMap属性值来源于SysRoleMapper.xml文件配置信息 。
* 根据用户ID查询用户信息、用户角色信息.
*
* @param id
* @return
*
* @author moon 2019/03/08 18:40
*/
SysUser selectUserAndRoleById6(Long id);
// 为突出本篇博客所述问题,在此处省略其他的函数。
}
3、SysRoleMapper.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.moon.mybatis.mapper.SysRoleMapper">
<resultMap id="BaseResultMap" type="com.moon.mybatis.pojo.SysRole"> <!-- 该行代码可在UserMapperTest.java中正确执行 -->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="role_name" jdbcType="VARCHAR" property="roleName" />
<result column="enabled" jdbcType="INTEGER" property="enabled" />
<result column="create_by" jdbcType="BIGINT" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
</resultMap>
<resultMap id="SysRoleMap" type="com.moon.mybatis.pojo.SysRole">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="role_name" jdbcType="VARCHAR" property="roleName" />
<result column="enabled" jdbcType="INTEGER" property="enabled" />
<result column="create_by" jdbcType="BIGINT" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
</resultMap>
<sql id="Base_Column_List">
id, role_name, enabled, create_by, create_time
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role
where id = #{id,jdbcType=BIGINT}
</select>
</mapper>
SysUserMapper.xml文件内容如下所示,在这里注意id为"userRoleMap6"的resultMap标签,其子标签association中的 resultMap属性值为:com.moon.mybatis.mapper.SysRoleMapper.BaseResultMap。
<?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.moon.mybatis.mapper.SysUserMapper">
<!-- Mybatis逆向生成工具自动生成的resultMap @moon 2019/03/09 16:41 -->
<resultMap id="sysUserMap" type="com.moon.mybatis.pojo.SysUser">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="user_name" jdbcType="VARCHAR" property="userName" />
<result column="user_password" jdbcType="VARCHAR" property="userPassword" />
<result column="user_email" jdbcType="VARCHAR" property="userEmail" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="user_info" jdbcType="LONGVARCHAR" property="userInfo" />
<result column="head_img" jdbcType="BLOB" property="headImg" />
</resultMap>
<!--
使用resultMap的association标签的resultMap属性配置一对一映射。
其中,association标签的resultMap属性值来源于SysRoleMapper.xml文件配置信息 。
-->
<!--
使用resultMap的association标签配置一对一映射。 @moon 2019/03/08 15:33
-->
<resultMap id="userRoleMap6" extends="sysUserMap" type="com.moon.mybatis.pojo.SysUser">
<association property="sysRole" columnPrefix="role_" resultMap="com.moon.mybatis.mapper.SysRoleMapper.BaseResultMap" />
</resultMap>
<!--
一对一映射,使用resultMap配置一对一映射关系.
使用resultMap的association标签的resultMap属性配置一对一映射。
其中,association标签的resultMap属性值来源于当前文件配置的信息。
-->
<!-- 根据用户ID查询用户信息、用户角色信息. @moon 2019/03/08 18:26 -->
<select id="selectUserAndRoleById6" parameterType="java.lang.Long" resultMap="userRoleMap6">
SELECT u.id,
u.user_name,
u.user_password,
u.user_email,
u.user_info,
u.head_img,
u.create_time,
r.id AS role_id,
r.role_name AS role_role_name,
r.enabled AS role_enabled,
r.create_by AS role_create_by,
r.create_time AS role_create_time
FROM sys_user u
INNER JOIN sys_user_role ur ON ur.user_id = u.id
INNER JOIN sys_role r ON ur.role_id = r.id
WHERE u.id = #{id}
</select>
</mapper>
4、BaseMapperTest.java文件内容如下所示:
package com.moon.mybatis.test;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
/**
* 基础测试类
*
* @author moon 2019/03/07 16:47
*/
public class BaseMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException ignore) {
ignore.printStackTrace();
}
}
public SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
UserMapperTest.java文件如下所示:
package com.moon.mybatis.test;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.moon.mybatis.mapper.SysUserMapper;
import com.moon.mybatis.pojo.SysUser;
/**
* 测试类,集中进行验证Mybatis的高级查询:
* 高级映射、存储过程、
* 枚举、JavaBean、JDK8
*
* @author moon 2019/03/07 16:57
*/
public class UserMapperTest extends BaseMapperTest {
/**
* 一对一映射
*
* @author moon 2019/03/08 11:28
*/
@Test
public void testSelectUserAndRoleById() {
// 获取 sqlSession
SqlSession sqlSession = getSqlSession();
try {
// 获取 UserMapper接口
SysUserMapper userMapper = sqlSession.getMapper(SysUserMapper.class);
/**
* selectUserAndRoleById6(...)函数可以执行,但没能得到sysRole属性值! @author moon 2019/03/10 11:01
*/
System.out.println("------------------------ Mybatis, 一对一映射,使用resultMap的association标签配置一对一映射. ------------------------");
SysUser user7 = userMapper.selectUserAndRoleById6(1001L);
System.out.println("user7为:" + user7.toString());
// user不为空
Assert.assertNotNull(user7);
} catch (Exception e) {
System.out.println("e的值为: " + e.toString());
// 提交事务
// sqlSession.commit();
// 事务回滚
sqlSession.rollback();
// 不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
程序运行Log日志结果如下所示,注意仔细观看 SysUser实体类中的 sysRole属性的值。
------------------------ Mybatis, 一对一映射,使用resultMap的association标签配置一对一映射. ------------------------
DEBUG [main] - ==> Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, u.user_info, u.head_img, u.create_time, r.id AS role_id, r.role_name AS role_role_name, r.enabled AS role_enabled, r.create_by AS role_create_by, r.create_time AS role_create_time FROM sys_user u INNER JOIN sys_user_role ur ON ur.user_id = u.id INNER JOIN sys_role r ON ur.role_id = r.id WHERE u.id = ?
DEBUG [main] - ==> Parameters: 1001(Long)
TRACE [main] - <== Columns: id, user_name, user_password, user_email, user_info, head_img, create_time, role_id, role_role_name, role_enabled, role_create_by, role_create_time
TRACE [main] - <== Row: 1001, test, 123456, [email protected], <<BLOB>>, <<BLOB>>, 2016-04-01 17:00:58.0, 2, 普通用户, 1, 1, 2016-04-01 17:02:34.0
DEBUG [main] - <== Total: 1
user7为:SysUser [id=1001, userName=test, userPassword=123456, [email protected], createTime=Fri Apr 01 17:00:58 CST 2016, userInfo=测试用户, headImg=null,
sysRole=SysRole [id=2, roleName=普通用户, enabled=1, createBy=1, createTime=Fri Apr 01 17:02:34 CST 2016]
]
若将 SysUserMapper.xml文件中的 id为"userRoleMap6"的resultMap标签,其子标签association中的 resultMap属性值为:com.moon.mybatis.mapper.SysRoleMapper.SysRoleMap, 则会报错!
SysUserMapper.xml文件修改的内容为:
<!--
使用resultMap的association标签的resultMap属性配置一对一映射。
其中,association标签的resultMap属性值来源于SysRoleMapper.xml文件配置信息 。
-->
<!--
使用resultMap的association标签配置一对一映射。 @moon 2019/03/08 15:33
-->
<resultMap id="userRoleMap6" extends="sysUserMap" type="com.moon.mybatis.pojo.SysUser">
<association property="sysRole" columnPrefix="role_" resultMap="com.moon.mybatis.mapper.SysRoleMapper.SysRoleMap" />
</resultMap>
UserMapperTest.java文件运行错误截图如下所示: