MyBatis教程:XML多表查询的基本使用
1.多表查询
在上一篇博客中,我们举例说明的两个查询都是单表查询,但实际业务场景肯定需要多表。比如查询,现在有一个需求:
查询某个用户拥有的所有角色s。这个需求涉及到三个表:sys_user、sys_user_role、sys_role。如何实施?
首先在SysUserMapper接口中定义以下方法。
/**
* 根据用户id获取角色信息
*
* @param userId
* @return
*/
List<SysRole> selectRolesByUserId(Long userId);
然后打开对应的SysUserMapper.xml文件,添加如下select语句:
<select id="selectRolesByUserId" resultType="com.zwwhnly.mybatisaction.model.SysRole">
SELECT r.id,
r.role_name roleName,
r.enabled,
r.create_by createBy,
r.create_time createTime
FROM sys_user u
INNER JOIN sys_user_role ur ON u.id = ur.user_id
INNER JOIN sys_role r ON ur.role_id = r.id
WHERE u.id = #{userId}
</select>
细心的读者可以发现,即使我们使用多表查询,resultType仍然设置为单表,即它只包含角色表信息。
如果我的希望查询也返回SysUser表中的用户名字段,我应该如何设置resultType?
方法一:直接在SysRole实体类中添加用户名字段。
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
此时不需要更改 ResultType。
方法二:新建一个扩展类,并将用户名字段添加到扩展类中。
package com.zwwhnly.mybatisaction.model;
public class SysRoleExtend extends SysRole {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
此时resultType应更改为:com.zwwhnly.mybatisaction.model.SysRoleExtend。
该方法比较适合需要少量额外字段的场景。如果需要大量其他表的字段,可以使用方法3或4,我个人推荐使用方法4。
方法3:在SysRole实体类中添加一个SysUser类型的字段。
private SysUser sysUser;
public SysUser getSysUser() {
return sysUser;
}
public void setSysUser(SysUser sysUser) {
this.sysUser = sysUser;
}
此时不需要更改ResultType。
方法四(推荐):新建一个扩展类,并在扩展类中添加一个SysUser类型的字段。
书上推荐的是方法3。方法4是我认为最好的方法,因为实体类一般都是由工具自动生成的。添加字段后,很容易忘记并在以后覆盖它们。
package com.zwwhnly.mybatisaction.model;
public class SysRoleExtend extends SysRole {
private SysUser sysUser;
public SysUser getSysUser() {
return sysUser;
}
public void setSysUser(SysUser sysUser) {
this.sysUser = sysUser;
}
}
此时resultType应更改为:com.zwwhnly.mybatisaction.model.SysRoleExtend。
此时xml中的查询语句如下。
<select id="selectRolesByUserId" resultType="com.zwwhnly.mybatisaction.model.SysRoleExtend">
SELECT r.id,
r.role_name roleName,
r.enabled,
r.create_by createBy,
r.create_time createTime,
u.user_name "sysUser.userName",
u.user_email "sysUser.userEmail"
FROM sys_user u
INNER JOIN sys_user_role ur ON u.id = ur.user_id
INNER JOIN sys_role r ON ur.role_id = r.id
WHERE u.id = #{userId}
</select>
在SysUserMapperTest中添加测试代码如下。
@Test
public void testSelectRolesByUserId() {
SqlSession sqlSession = getSqlSession();
try {
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
List<SysRole> sysRoleList = sysUserMapper.selectRolesByUserId(1L);
Assert.assertNotNull(sysRoleList);
Assert.assertTrue(sysRoleList.size() > 0);
} finally {
sqlSession.close();
}
}
运行此测试方法并输入日志如下。
DEBUG [main] - ==> 准备: SELECT r.id, r.role_name roleName, r.enabled, r.create_by createBy, r.create_time createTime, u.user_name "sysUser.userName", "u.user_email " sysUser.userEmail" FROM sys_user u INNER JOIN sys_user_role ur ON u.id = ur.user_id INNER JOIN sys_role r ON ur.role_id = r.id WHERE u.id = ? ==>主参数]DE:G 1 (长)
TRACE [main] -
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。