海创软件组-MyBatis一对多和多对多应用

MyBatis一对多和多对多应用

mybatis3.0 添加了association和collection标签专门用于对多个相关实体类数据进行级联查询,但仍不支持多个相关实体类数据的级联保存和级联删除操作。因此在进行实体类一对多和多对多映射表设计时,需要专门建立一个关联对象类对相关实体类的关联关系进行描述。

1.应用场景

设计数据库表,假设现在有角色,人员,部门三级关系,其中角色对人员是多对多,人员对部门是多对一,设计中间表和表内字段实现根据部门查询所属员工,根据员工查询所属角色.

2.环境搭建

我们首先在创建一个 java 工程,工程名称为:01-mybatis-der,笔者使用的是jdk1.8下面是笔者使用的jar:
海创软件组-MyBatis一对多和多对多应用_第1张图片

3.准备工作

创建5张表,它们分别是部门表 department,员工表employee,角色表 role, 部门员工映射表 department_employee和员工角色映射表employee_role,一个部门可以有多个员工,一个员工可以有多个角色,一个角色也可以有多个员工。项目工程结构如下:
海创软件组-MyBatis一对多和多对多应用_第2张图片
使用Navicat for MySQL创建表
department表
在这里插入图片描述employee表
在这里插入图片描述
department_employee表
在这里插入图片描述role表
在这里插入图片描述
employee_role表
在这里插入图片描述
每一张表的主键都是自增的

4.创建表对应的JavaBean对象

一个表对应一个实体类

部门实体类

public class Department implements Serializable {
	
	private Integer did; //部门id
	private String dname; //部门名称
	private List<Employee> employees; //部门的员工
	//无参构造构造,有参构造,setter,getter,toString方法这里就省略了

员工实体类

public class Employee implements Serializable {
	
	private Integer eid; //员工id
	private String ename; //员工名字
	private int eage; //员工年龄
	private List<Role> roles; //员工扮演的角色
	//无参构造构造,有参构造,setter,getter,toString方法这里就省略了

部门员工映射实体类

public class DepartmentEmployee implements Serializable {
	
	private Integer deId; //部门组映射id
	private Integer departmentId; //部门id
	private Integer employeeId; //员工id
	//无参构造构造,有参构造,setter,getter,toString方法这里就省略了

角色实体类

public class Role implements Serializable {
	
	private Integer rid; //角色id
	private String rname; //角色名字
	private List<Employee> employees; //这个角色的全部员工
	//无参构造构造,有参构造,setter,getter,toString方法这里就省略了

员工角色映射实体类

public class EmployeeRole implements Serializable {
	
	private Integer erId; //员工角色映射id
	private Integer employeeId; // 员工id
	private Integer roleId; // 角色id
	//无参构造构造,有参构造,setter,getter,toString方法这里就省略了

4.配置文件

mybatis的配置文件有主配置文件和映射配置文件,我们先写主配置文件,我把放在src目录下,文件名为mybatis.xml,其详细情况如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration  
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
	"http://mybatis.org/dtd/mybatis-3-config.dtd"> 
<configuration>
	<!-- 	指出jdbc属性文件所在位置 -->
	<properties resource="jdbc.properties"/>
	
	<!-- 	注册类型别名 -->
	<typeAliases>
		<package name="com.haichuang.beans"/>
	</typeAliases>

	<!-- 	注册数据源 -->
	<environments default="mysql">
		<environment id="mysql">
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}"/>
				<property name="url" value="${jdbc.url}"/>
				<property name="username" value="${jdbc.username}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 	注册映射文件 -->
	<mappers>
		<mapper resource="com/haichuang/daos/employee-mapper.xml"/>
		<mapper resource="com/haichuang/daos/role-mapper.xml"/>
		<mapper resource="com/haichuang/daos/department-mapper.xml"/>
		<mapper resource="com/haichuang/daos/employee-role-mapper.xml"/>
		<mapper resource="com/haichuang/daos/department-employee-mapper.xml"/>
	</mappers>
	
</configuration>

员工和角色的多对多查询

mybatis通过mapper动态代理直接调用接口方法,这里我们需要创建一个接口

Employee实体类对应的接口

package com.haichuang.daos;

import com.haichuang.beans.Employee;

public interface IEmployeeDao {

	public Employee selectEmployeeById(int eid);
}

Role实体类对应的接口

package com.haichuang.daos;

import com.haichuang.beans.Role;

public interface IRoleDao {

	public Role selectRoleById(int rid);
}

EmployeeRole实体类对应的接口

package com.haichuang.daos;

import java.util.List;
import java.util.Set;

import com.haichuang.beans.Employee;
import com.haichuang.beans.Role;

public interface IEmployeeRoleDao {

	public List<Role> selectRoleByEmployeeId(int eid);
	public List<Employee> selectEmployeeByRoleId(int rid);
}

IEmployeeDao .java 对应的配置文件 src/com/haichuang/daos/employee-mapper.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.haichuang.daos.IEmployeeDao">
	
	<!-- 	员工的mapper -->
	<!-- 	collection标签子标签select通过Role对应的映射文件来获取员工信息 -->
	<resultMap type="Employee" id="employeetMapper">
		<id column="eid" property="eid"/>
		<result column="ename" property="ename"/>
		<result column="eage" property="eage"/>
		<collection property="roles" 
					ofType="Role"
					select="com.haichuang.daos.IEmployeeRoleDao.selectRoleByEmployeeId"
					column="eid"/>
	</resultMap>
		
	<!-- 	通过id查询员工 -->
	<select id="selectEmployeeById" resultMap="employeetMapper">
		select eid,ename,eage from employee where eid = #{eid}
	</select>
</mapper>

IRoleDao .java 对应的配置文件 src/com/haichuang/daos/role-mapper.xml 的内容如下:

<!DOCTYPE mapper  
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.haichuang.daos.IRoleDao">
	
	<!-- 	角色的mapper -->
	<!-- 	collection标签子标签select通过Employee对应的映射文件来获取角色信息 -->
	<resultMap type="role" id="roleMapper">
		<id column="rid" property="rid"/>
		<result column="rname" property="rname"/>
		<collection property="employees" 
					ofType="Employee"
					select="com.haichuang.daos.IEmployeeRoleDao.selectEmployeeByRoleId"
					column="rid"/>
	</resultMap>

	<!-- 	通过id来查询角色信息 -->
	<select id="selectRoleById" resultMap="roleMapper">
		select rid,rname from role where rid = #{xxx}
	</select>
</mapper>

IEmployeeRoleDao .java 对应的配置文件 src/com/haichuang/daos/employee-role-mapper.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.haichuang.daos.IEmployeeRoleDao">

	<resultMap type="Role" id="roleMapper">
		<id column="rid" property="rid"/>
		<result column="rname" property="rname"/>
	</resultMap>

	<!-- 	通过传来的员工id查询员工角色中间表进而确定员工对象的角色信息 -->
	<select id="selectRoleByEmployeeId" resultMap="roleMapper">
		select rid,rname 
		from role
		inner join employee_role on employeeId = #{xxx}
		where rid = roleId
	</select>
	
	<resultMap type="Employee" id="employeeMapper">
		<id column="eid" property="eid"/>
		<result column="ename" property="ename"/>
	</resultMap>
	
	<!-- 	通过传来的角色id查询员工角色中间表进而确定员工对象的信息 -->
	<select id="selectEmployeeByRoleId" resultMap="employeeMapper">
		select eid,ename 
		from employee
		inner join employee_role on roleId = #{xxx}
		where eid = employeeId
	</select>
	
</mapper>

到这里我们员工对角色的多对多关系查询就完成了

部门对员工的一对多查询

Department实体类对应的接口

package com.haichuang.daos;

import com.haichuang.beans.Department;

public interface IDepartmentDao {

	public Department selectDepartmentById(int did);
}

DepartmentEmployee实体类对应的接口

package com.haichuang.daos;

import java.util.List;
import java.util.Set;

import com.haichuang.beans.Employee;

public interface IDepartmentEmployeeDao {

	public List<Employee> selectEmployeeByDepartmentId(int did);
}

IDepartmentDao .java 对应的配置文件 src/com/haichuang/daos/department-mapper.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.haichuang.daos.IDepartmentDao">
	
	<!-- 	部门的mapper -->
	<!-- 	collection标签子标签select通过DepartmentEmployee对应的映射文件来获取员工信息 -->
	<resultMap type="Department" id="departmentMapper">
		<id column="did" property="did"/>
		<result column="dname" property="dname"/>
		<collection property="employees" 
					ofType="Employee"
					select="com.haichuang.daos.IDepartmentEmployeeDao.selectEmployeeByDepartmentId"
					column="did"/>
	</resultMap>
		
	<!-- 	通过id查询部门 -->
	<select id="selectDepartmentById" resultMap="departmentMapper">
		select did,dname from department where did = #{xxx}
	</select>
</mapper>

DepartmentEmployee.java 对应的配置文件 src/com/haichuang/daos/department-employee-mapper.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.haichuang.daos.IDepartmentEmployeeDao">

	<!-- 	从部门员工表中查询出员工的id,然后用这个id通过employee的mapper配置文件查询员工信息 -->
	<select id="selectEmployeeByDepartmentId" resultMap="com.haichuang.daos.IEmployeeDao.employeetMapper">
		select eid,ename,eage 
		from  employee
		inner join department_employee on departmentId = #{xxx}
		where eid = employeeId
	</select>
	
</mapper>

5.mybatis的工具类

这个不是这个例子的重点,笔者就不再解析了

package com.haichuang.utils;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisUtils 
{
	public static SqlSession getSqlSession() {
		try {
			//1.加载主配置文件
			InputStream in = Resources.getResourceAsStream("mybatis.xml");
			if(sqlSessionFactory == null) {
				//2.创建SqlSessionFactory对象
				sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
			}
			//3.创建SqlSession对象并返回
			return sqlSessionFactory.openSession();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	private static SqlSessionFactory sqlSessionFactory;
}

6.测试程序运行

到这里,整个工作准备得已经差不多了,我们创建一个主类来测试上面程序,在 src 的com.haichuang.test创建一个 MyTest.java,代码如下:

package com.haichuang.test;

import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.haichuang.beans.Department;
import com.haichuang.beans.Employee;
import com.haichuang.beans.Role;
import com.haichuang.daos.IDepartmentDao;
import com.haichuang.daos.IEmployeeDao;
import com.haichuang.daos.IRoleDao;
import com.haichuang.utils.MybatisUtils;

public class MyTest {

	@Before
	public void before(){
		sqlSession=MybatisUtils.getSqlSession();
		//edao = sqlSession.getMapper(IEmployeeDao.class);
		//rdao = sqlSession.getMapper(IRoleDao.class);
		ddao = sqlSession.getMapper(IDepartmentDao.class);
	}
	
	@After
	public void after() {
		if(sqlSession != null) {
			sqlSession.close();
		}
	}
	
	@Test
	public void test01() {
		Employee employee = null;
		employee = edao.selectEmployeeById(1);
		System.out.println(employee);
	}
	
	@Test
	public void test02() {
		Role role = null;
		role = rdao.selectRoleById(2);
		System.out.println(role);
	}
	
	@Test
	public void test03() {
		Department department = null;
		department = ddao.selectDepartmentById(1);
		System.out.println(department);
	}
	
	private IEmployeeDao edao;
	private IRoleDao rdao;
	private IDepartmentDao ddao;
	private SqlSession sqlSession;
}

test01运行结果:
海创软件组-MyBatis一对多和多对多应用_第3张图片
test02运行结果:
海创软件组-MyBatis一对多和多对多应用_第4张图片
test03运行结果:
海创软件组-MyBatis一对多和多对多应用_第5张图片

你可能感兴趣的:(海创软件组)