【MyBatis】Mybatis 多表查询(二)多对多
- 需求:
实现查询所有对象并且加载它所分配的用户信息。 - 分析:
查询角色我们需要用到Role表,但角色分配的用户的信息我们并不能直接找到用户信息,而是要通过中间表(USER_ROLE 表)才能关联到用户信息。
案例前提数据库中已经存在user,role表,以及中间表user_role
那么我们的sql语句应该是:
SELECT
r.*,u.id uid,u.username username,u.birthday birthday,u.sex sex,u.address address
FROM ROLE r
INNER JOIN USER_ROLE ur ON ( r.id = ur.rid)
INNER JOIN USER u ON (ur.uid = u.id);
角色实体类:
package com.siyi.domain;
import java.io.Serializable;
import java.util.List;
public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
//多对多的关系映射,一个角色可以赋予多个用户
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"roleId=" + roleId +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
IRole 持久层接口
package com.siyi.dao;
import com.siyi.domain.Role;
import java.util.List;
public interface IRoleDao {
/**
* 查询所有角色
* @return
*/
public List<Role> findAll();
}
映射文件IRoleDao.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.siyi.dao.IRoleDao">
<!-- 定义role表的ResultMap -->
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"/>
<result property="roleName" column="role_name"/>
<result property="roleDesc" column="role_desc"/>
<collection property="users" ofType="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
</collection>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id = ur.rid
left outer join user u on u.id = ur.uid
</select>
</mapper>
测试类
package com.siyi.test;
import com.siyi.dao.IRoleDao;
import com.siyi.dao.IUSerDao;
import com.siyi.domain.Role;
import com.siyi.domain.User;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class RoleTest {
private InputStream in;
private SqlSession session;
private IRoleDao iRoleDao;
@Before//用于在测试方法执行之前执行
public void init() throws IOException {
//1.读取配置文件生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.获取SqlSession对象
session = factory.openSession(true);
//4.获取DAO的代理对象
iRoleDao = session.getMapper(IRoleDao.class);
}
@After//用于在测试方法之后执行
public void destroy() throws IOException {
//事务提交
//session.commit();
//释放资源
session.close();
in.close();
}
/**
* 测试查询所有
* @throws IOException
*/
@Test
public void testFindAll() throws IOException {
//5.执行查询所有方法
List<Role> roles = iRoleDao.findAll();
for (Role role : roles) {
System.out.println("------------------------");
System.out.println(role);
System.out.println(role.getUsers());
}
}
}