Mybatis_09多表查询之多对多

第一步:编写角色到用户一对多

1、引入

问题: 查询角色获取角色下的用户信息

实现: Role 到 User 多对多

需求: 实现查询所有角色并且加载它所分配的用户信息。

分析: 查询角色我们需要用到Role表,但角色分配的用户信息我们不能直接找到用户信息而是要通过中间表(user_role表)才能关联到用户信息。

编写步骤

1、建立两张表:用户表,角色表
	让用户表和角色表具有多对多的关系。需要使用中间表,中间表中包含各自的主键,
	在中间表中是外键。
2、建立两个实体类:用户实体类和角色实体类
	让用户和角色的实体类能体现出多对多的关系
	各自包含对方一个集合引用
	
	代码部分:添加属性角色实体类包含用户实体类
		//多对多的关系映射:一个角色可以赋予多个用户
		private List<User> users;
		public void setUsers(List<User> users) {
			this.users = users;
		}
		public List<User> getUsers() {
			return users;
		}
		/
3、建立两个配置文件
	用户的配置文件
	角色的配置文件(角色配置中包含用户配置信息,利用collection标签包含)
	<!-- 定义Role的resultMap -->
	<resultMap id="roleMap" type="role">
		<id property="roleId" column="rid"></id>
		<result property="roleName" column="role_name"></result>
		<result property="roleDesc" column="role_desc"></result>
		<collection property="users" ofType="user">
			<id column="id" property="id"/>
			<result column="username" property="username"/>
			<result column="birthday" property="birthday"/>
			<result column="address" property="address"/>
			<result column="sex" property="sex"/>
			
		</collection>
	</resultMap>

4、实现配置
	当我们查询用户时,可以同时得到用户所包含的角色信息
	当我们查询角色时,可以同时得到角色的所赋予的用户信息(采用左连接将三个表连接起来)
	<!-- 查询所有 -->
	<select id="findRolelAll" 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>

2、编写实体类

public class User implements Serializable{
	private Integer id;
	private String username;
	//private	Date birthday;
	private String sex;
	private String address;
					···//
}
public class Role implements Serializable{
	private Integer roleId;
	private String roleName;
	private String roleDesc;
	
	//多对多的关系映射:一个角色可以赋予多个用户
	private List<User> users;
	public void setUsers(List<User> users) {
		this.users = users;
	}
	public List<User> getUsers() {
		return users;
	}								...//
}

3、编写持久层接口

/**
 * @author 
 *	用户的持久层接口
 *	mybatis的映射配置文件位置必须和dao接口的包结构相同
 */
public interface IRoleDao {
	/**
	 * 	查询所有Role角色
	 * @return
	 */

	List<Role> findRolelAll();

}

4、编写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.song.dao.IRoleDao">
	<!-- 配置查询所有 -->
	
	<!-- 定义Role的resultMap -->
	<resultMap id="roleMap" type="role">
		<id property="roleId" column="rid"></id>
		<result property="roleName" column="role_name"></result>
		<result property="roleDesc" column="role_desc"></result>
		<collection property="users" ofType="user">
			<id column="id" property="id"/>
			<result column="username" property="username"/>
			<!--<result column="birthday" property="birthday"/> -->
			<result column="address" property="address"/>
			<result column="sex" property="sex"/>
			
		</collection>
	</resultMap>
	
	<!-- 查询所有 -->
	<select id="findRolelAll" 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>

在这里插入图片描述

5、编写测试类

package com.song.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.song.dao.IRoleDao;

import com.song.domain.Role;

public class RoleTest {
	private InputStream in;
	private SqlSessionFactory factory;
	private SqlSession sqlSession;
	private IRoleDao roleDao;
	
	@Before
	public void init() throws IOException {
		//1、读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2、创建SqlSessionFactory工厂(工厂模式)
		factory= new SqlSessionFactoryBuilder().build(in);
		//3、使用工厂生产SqlSesson对象
		sqlSession = factory.openSession(true);//手动将事务提交方式改为自动提交
		//4、使用SqlSession创建Dao接口的代理对象
		
		roleDao = sqlSession.getMapper(IRoleDao.class);
	}
	@After//用于在测试方法执行之后执行
	public void destory() throws Exception {
		//提交事务
		//sqlSession.commit();
		//6、释放资源
		sqlSession.close();
		in.close();
	}
	
	/**
	 * 查询所有角色
	 */
	@Test
	public void testfindAll() {
		List<Role> roles = roleDao.findRolelAll();
		for(Role role:roles) {
			System.out.print("这是一条记录:");
			System.out.print(role);
			System.out.println(role.getUsers());
			
		}
	}
}


6、测试结果

一个角色对应多个用户,一个用户对应多个角色。
在这里插入图片描述

第二步:编写用户到角色一对多

1、引入

问题: 查询用户获取角色信息

实现: User到 Role 多对多

需求: 实现查询所有对象并且加载它所分配的用户信息。

分析: 查询角色我们需要用到Role表,但角色分配的用户信息我们不能直接找到用户信息而是要通过中间表(user_role表)才能关联到用户信息。

编写步骤

1、建立两张表:用户表,角色表
	让用户表和角色表具有多对多的关系。需要使用中间表,中间表中包含各自的主键,
	在中间表中是外键。
2、建立两个实体类:用户实体类和角色实体类
	让用户和角色的实体类能体现出多对多的关系
	各自包含对方一个集合引用
	
	代码部分:添加属性用户实体类包含角色实体类
		//多对多的关系映射:一个角色可以赋予多个用户
		//多对多的关系映射:一个用户可以是多个角色
		private List<Role> roles;
		public void setRoles(List<Role> roles) {
			this.roles = roles;
		}
		public List<Role> getRoles() {
			return roles;
		}
3、建立两个配置文件
	用户的配置文件(用户配置中包含角色配置信息,利用collection标签包含)
	<!-- 配置查询所有 -->
	<resultMap type="user" id="userMap">
		<id column="id" property="id"></id>
		<result column="birthday" property="birthday"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
		<result column="username" property="username"/>
		<collection property="roles" ofType="role">
			<id column="rid" property="roleId"></id>
			<result column="role_name" property="roleName"/>
			<result column="role_desc" property="roleDesc"/>
		</collection>
	</resultMap>	
	角色的配置文件

4、实现配置
	当我们查询用户时,可以同时得到用户所包含的角色信息(采用左连接将三个表连接起来)
	<!-- 查询所有 -->
	<select id="findAll" resultMap="userMap">
		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>
	当我们查询角色时,可以同时得到角色的所赋予的用户信息
		

2、编写实体类

public class Role implements Serializable{
	private Integer roleId;
	private String roleName;
	private String roleDesc;
	
	//多对多的关系映射:一个角色可以赋予多个用户
	private List<User> users;
	public void setUsers(List<User> users) {
		this.users = users;
	}
	public List<User> getUsers() {
		return users;
	}
					···//
}
public class User implements Serializable{
	
	private Integer id;
	private String username;
	private	Date birthday;
	private String sex;
	private String address;
	
	//多对多的关系映射:一个用户可以是多个角色
	private List<Role> roles;
	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}
	public List<Role> getRoles() {
		return roles;
	}
									...//
}

3、编写持久层接口

public interface IRoleDao {
	/**
	 * 	查询所有Role角色
	 * @return
	 */

	List<Role> findRolelAll();

}
/**
 * 
 * @author 宋强
 *	用户的持久层接口
 *
 *mybatis的映射配置文件位置必须和dao接口的包结构相同
 */
public interface IUserDao {
	/**
	 * 	查询所有操作:同时获取 用户
	 */
	List<User> findAll();
}

4、编写IUserDao.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.song.dao.IUserDao">
	<!-- 配置查询所有 -->
		
	<!-- 定义一个User的resultMap -->
	<resultMap id="userAccountMap" type="user">
		<id property="id" column="id"></id>
		<result property="username" column="username"></result>
		<result property="address" column="address"></result>
		<result property="sex" column="sex"></result>
		<result property="birthday" column="birthday"></result>
		<!-- 配置user对象中accounts集合的映射 -->
		<collection property="accounts" ofType="account">
			<id property="id" column="aid"></id>
			<result property="uid" column ="uid"></result>
			<result property="money" column ="money"></result>
		</collection>
	</resultMap>
	
	<!-- 查询所有 -->
	<select id="findAll" resultMap="userAccountMap">
		select user.*,account.money,account.uid,account.id as aid from user left outer join account on user.id=account.uid
	</select>
	
</mapper>

编写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.song.dao.IRoleDao">
	<!-- 配置查询所有 -->
	
	<!-- 定义Role的resultMap -->
	<resultMap id="roleMap" type="role">
		<id property="roleId" column="rid"></id>
		<result property="roleName" column="role_name"></result>
		<result property="roleDesc" column="role_desc"></result>
		<collection property="users" ofType="user">
			<id column="id" property="id"/>
			<result column="username" property="username"/>
			<result column="birthday" property="birthday"/>
			<result column="address" property="address"/>
			<result column="sex" property="sex"/>
			
		</collection>
	</resultMap>
	<!-- 查询所有 -->
	<select id="findRolelAll" 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>

5、编写测试类

测试类UserTest

package com.song.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.song.dao.IUserDao;
import com.song.domain.User;

public class UserTest {
	private InputStream in;
	private SqlSessionFactory factory;
	private SqlSession sqlSession;

	private IUserDao userDao;
	
	@Before
	public void init() throws IOException {
		//1、读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2、创建SqlSessionFactory工厂(工厂模式)
		factory= new SqlSessionFactoryBuilder().build(in);
		//3、使用工厂生产SqlSesson对象
		sqlSession = factory.openSession(true);//手动将事务提交方式改为自动提交
		//4、使用SqlSession创建Dao接口的代理对象
		
		userDao = sqlSession.getMapper(IUserDao.class);
	}
	@After//用于在测试方法执行之后执行
	public void destory() throws Exception {
		//提交事务
		//sqlSession.commit();
		//6、释放资源
		sqlSession.close();
		in.close();
	}
	
	/**
	 * 查询账户所有
	 */
	@Test
	public void testfindAllcount() {
		List<User> users = userDao.findAll();
		for(User user:users) {
			System.out.print("这是一条记录:");
			System.out.println(user);
			System.out.println(user.getAccounts());
		}
	}
}

测试结果:
一个用户对应多个角色,一个角色对应多个用户。
在这里插入图片描述

测试类RoleTest

public class RoleTest {
	private InputStream in;
	private SqlSessionFactory factory;
	private SqlSession sqlSession;
	private IRoleDao roleDao;
	
	@Before
	public void init() throws IOException {
		//1、读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2、创建SqlSessionFactory工厂(工厂模式)
		factory= new SqlSessionFactoryBuilder().build(in);
		//3、使用工厂生产SqlSesson对象
		sqlSession = factory.openSession(true);//手动将事务提交方式改为自动提交
		//4、使用SqlSession创建Dao接口的代理对象
		
		roleDao = sqlSession.getMapper(IRoleDao.class);
	}
	@After//用于在测试方法执行之后执行
	public void destory() throws Exception {
		//提交事务
		//sqlSession.commit();
		//6、释放资源
		sqlSession.close();
		in.close();
	}
	
	/**
	 * 查询所有角色
	 */
	@Test
	public void testfindAll() {
		List<Role> roles = roleDao.findRolelAll();
		for(Role role:roles) {
			System.out.print("这是一条记录:");
			System.out.print(role);
			System.out.println(role.getUsers());
			
		}
	}
}

测试结果
一个role对应多个用户,一个用户有多个role
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值