自动映射
在 select 标签中通过设置别名的方式实现自动将值匹配到字段上。XML 代码如下(SysUser 类中已加入 SysRole 字段):
<select id="selectUserAndRoleById" resultType="tk.mybatis.simple.model.SysUser" parameterType="java.lang.Long">
select
u.id,
u.user_name userName,
u.user_password userPassword,
u.user_info userInfo,
u.create_time createTime,
r.role_name as "role.roleName",//
r.enabled as "role.enabled"
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>
通过设置别名让 MyBatis 自动将值匹配到对应的字段上,sys_role 查询列的别名需要加“ role .”前缀。
结果映射
也可以使用 resultMap 配置结果映射:在 UserMapper.xml 中增加下面 resultMap:
<resultMap id="userRoleMap" type="tk.mybatis.simple.model.SysUser" extends="userMap">
<result property="role.id" column="role_id"/>
<result property="role.roleName" column="role_name"/>
<result property="role.enabled" column="enabled"/>
<result property="role.createBy" column="create_by"/>
<result property="role.createTime" column="role_create_time" jdbcType="TIMESTAMP"/>
</resultMap>
只需注意查询别名和配置的 column 一致即可。
<select id="selectUserAndRoleById2" resultMap="userRoleMap">
select
u.id,
u.user_name,
u.user_password,
u.user_info,
u.create_time,
r.id role_id,
r.role_name role_name,
r.enabled enabled,
r.create_by create_by,
r.create_time role_create_time
from sys_user u
inner join sys_user_role ur on u.id = ur.user_id
inner join sys_role r on r.id = ur.role_id
where u.id = #{id}
</select>
使用association标签配置
在 resultMap 中,association 标签用户和一个复杂的类型进行关联,即用于一对一的关联配置。
标签下属性 | 作用 |
---|---|
property | 对应实体类中的属性名,必填项 |
javaType | 属性对应的Java类型 |
resultMap | 可以直接使用现有的 resultMap |
columnPrefix | 查询列的前缀,配置后,在子标签配置column时可以省略前缀 |
改良后的写法:
<resultMap id="userRoleMap" type="tk.mybatis.simple.model.SysUser" extends="userMap">
<association property="role" javaType="tk.mybatis.simple.model.SysRole"
columnPrefix="role_">
<result property="id" column="id"/>
<result property="roleName" column="role_name"/>
<result property="enbaled" column="enabled"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</association>
</resultMap>
<select id="selectUserAndRoleById2" resultMap="userRoleMap">
select
u.id,
u.user_name,
u.user_password,
u.user_info,
u.create_time,
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
from sys_user u
inner join sys_user_role ur on u.id = ur.user_id
inner join sys_role r on r.id = ur.role_id
where u.id = #{id}
</select>
association标签的嵌套查询
association标签的嵌套查询常用的属性如下:
select | 另一个映射查询的 id,MyBatis会额外执行这个查询获取结果;最好使用全限定名 |
column | 列名(或别名),将主查询中列的结果作为嵌套查询的参数,配置方式为 column={prop1=col1,prop2=col2}, prop1 和 prop2 将作为参数 |
fetchType | 数据加载方式,可选值为 lazy 和 eager,分别为延迟加载和积极加载,会覆盖全局的lazyLoadingEnabled配置 |
若查询出来的结果并没有被使用则会浪费资源,延迟加载可以避免这种情况,在mybatis-config文件中要将 aggressiveLazyLoading 设置为 false 延迟加载才能生效
在另一xml文件中的子查询 selectRoleById
<select id="selectRoleById" resultMap="roleMap">
select * from sys_role where id = #{id}
</select>
使用嵌套查询的 resultMap:
<resultMap id="userRoleMapSelect" type="tk.mybatis.simple.model.SysUser"
extends="userMap">
<association property="role" column="{id=role_id}" fetchType="lazy"
select="tk.mybatis.simple.mapper.RoleMapper.selectRoleById"/>
</resultMap>
<select id="selectUserAndRoleByIdSelect" resultMap="userRoleMapSelect">
select
u.id,
u.user_name,
u.user_password,
u.user_info,
u.create_time,
ur.role_id
from sys_user u
inner join sys_user_role ur on ur.user_id = u.id
where u.id = #{id}
</select>
如果有些时候需要在触发某方法时将所有的数据都加载进来,而已经将 aggressiveLazyLoading 设置为 false,MyBatis 提供了参数 lazyLoadTriggerMethods 来解决这个问题。此参数的含义是,当调用配置中的方法时,加载全部的延迟加载数据,默认值是" equals,clone,hashCode,toString",因此只要调用查询对象的其中一个方法,就可以实现加载调用对象的全部数据。