1、ResultMap的association与collection association与collection功能类似,区别是一对一与一对多,这里以association为例。
首先说明一下需求:通过员工ID获取员工信息,同时获取员工的角色,涉及到了员工信息表、角色表、还有二者的关联表。最简单的做法是写一个SQL语句,语句里写了三个表,互相关联进行查询,但这种方式存在问题:1、SQL语句不易维护 2、复用性不强 3、我只想获取用户的信息,不用角色信息时,查询了多余的信息,徒增消耗。
解决办法:1、对每个实体都定义一个基础的ResultMap,根据需要继承基础ResultMap再添加自定义的属性 2、在ResultMap中使用association或者collection进行关联查询 3、使用延迟加载,需要角色信息时再去查询。
实际操作过程:
新建实体类User和Role
import java.util.Date;
public class Role {
private Long id;
private String roleName;
private Integer enabled;
private Long createBy;
private Date createTime;
private Long updateBy;
private Date updateTime;
...
getter和setter就省略了
...
}
import java.util.Date;
import java.util.List;
public class User {
private Long id;
private String userName;
private String userPassword;
private String userPhone;
private String userEmail;
private Date createTime;
private Date updateTime;
private byte[] headImg;
private Role role;
...
getter和setter省略了
...
}
然后编写Mapper.xml
首先先编写其中的字段映射部分BaseResultMap。
UserMapper.xml
<resultMap id="BaseResultMap" type="com.forest.owl.entity.User">
<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_phone" jdbcType="VARCHAR" property="userPhone" />
<result column="user_email" jdbcType="VARCHAR" property="userEmail" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="head_img" jdbcType="LONGVARBINARY" property="headImg" />
</resultMap>
RoleMapper.xml
<resultMap id="BaseResultMap" type="com.forest.owl.entity.Role">
<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" />
<result column="update_by" jdbcType="BIGINT" property="updateBy" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
编写RoleMapper.xml获取Role的接口和XML
import com.forest.owl.entity.Role;
public interface RoleMapper {
Role selectByPrimaryKey(Long id);
}
RoleMapper.xml
<select id="selectByPrimaryKey" resultMap="BaseResultMap">
select id, role_name, enabled, create_by, create_time, update_by, update_time
from role
where id = #{id,jdbcType=BIGINT}
</select>
然后编写UserMapper.xml
<resultMap id="UserAndRole" extends="BaseResultMap" type="com.forest.owl.entity.User">
<association property="role" fetchType="lazy" column="{id=role_id}" select="com.forest.owl.mapper.RoleMapper.selectByPrimaryKey"/>
</resultMap>
<select id="selectUsersById" resultMap="UserAndRole">
SELECT u.*, ur.role_id
FROM user u
INNER JOIN user_role ur on ur.user_id=u.id
WHERE u.id=#{id}
</select>
可以看到,UserMapper的SQL语句中少了role表,这样SQL语句就简洁多了。需要注意,association中的fetchType=“lazy”选项,当执行getRole()的时候,才回去查询角色信息加载到查询结果中。如果用户还是需要在触发某个方法时加载全部数据,则可以配置mybatis的配置选项lazyLoadTriggerMethods,按需加载。
对于3.4.1 及之前版本的mybatis用户,还需要配置mybatis-config.xml的一个选项:
<setting name="aggressiveLazyLoading" value="false"/>
测试:
@Test
public void UserMapperTest(){
SqlSession sqlSession = getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.selectUsersById((long) 2);
System.out.println(userList.size());
System.out.println("--------getRole---------");
System.out.println(userList.get(0).getRole());
}
执行结果
collection的代码
import java.util.Date;
import java.util.List;
public class User {
private Long id;
private String userName;
private String userPassword;
private String userPhone;
private String userEmail;
private Date createTime;
private Date updateTime;
private byte[] headImg;
private List<Role> roleList;
...
getter和setter省略
...
}
<?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.forest.owl.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.forest.owl.entity.User">
<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_phone" jdbcType="VARCHAR" property="userPhone" />
<result column="user_email" jdbcType="VARCHAR" property="userEmail" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="head_img" jdbcType="LONGVARBINARY" property="headImg" />
</resultMap>
<resultMap id="UserAndRole" extends="BaseResultMap" type="com.forest.owl.entity.User">
<collection property="roleList" columnPrefix="role_" fetchType="lazy"
resultMap="com.forest.owl.mapper.RoleMapper.BaseResultMap">
<id property="id" column="id"/>
<result column="role_name" property="roleName" />
<result column="enabled" property="enabled" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
</collection>
</resultMap>
<select id="selectUsersById" resultMap="UserAndRole">
SELECT u.*,
r.id role_id,
r.role_name role_role_name,
r.enabled role_enabled,
r.create_by role_create_by,
r.create_time role_create_time,
r.update_by role_update_by,
r.update_time role_update_time
FROM user u
INNER JOIN user_role ur on ur.user_id=u.id
INNER JOIN role r on r.id=ur.role_id
WHERE u.id=#{id}
</select>
</mapper>
UserMapper接口
import com.forest.owl.entity.User;
public interface UserMapper {
User selectUsersById(Long id);
}
@Test
public void UserMapperTest(){
SqlSession sqlSession = getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectUsersById((long) 2);
System.out.println(user.getRoleList().get(0).getRoleName());
System.out.println(user.getRoleList().get(1).getRoleName());
}
转载于:https://my.oschina.net/u/4108765/blog/3059549