一、概述
MyBatis 中的一对多、多对一和多对多,主要就是 resultMap 中:
- association:一个复杂的类型关联。许多结果将包成这种类型(一对多)
- collection:复杂类型的集合(多对一)
这2个属性的使用,而一对多和多对一都是相互的,只是站的角度不同。
实例: 这个实例只说这2个属性的使用方法。
- 首先是数据库,以员工管理系统的数据库为例。
- 实体类:
这里只列要实现映射功能用到的类 user、role、department。
- department 和 user,是一对多关系,一个部门可以拥有多个员工。
- role和user是多对多关系,一个角色可能有多个员工,而一个员工也可能有多个角色。而要实现多对多,在程序中则是拆分成两个一对多,详情见下面的实体类注释。
1)User.java
@Data
public class User {
private int user_id;
private String user_name;
private String user_gender;
private String user_email;
private String user_phone;
private String user_address;
private Date user_birthday;
private int department_id;
private List<Role> roles;
private Department department;
public User() {
super();
}
public User(String user_name, String user_gender,
String user_email, String user_phone, String user_address,
Date user_birthday, int department_id) {
super();
this.user_name = user_name;
this.user_gender = user_gender;
this.user_email = user_email;
this.user_phone = user_phone;
this.user_address = user_address;
this.user_birthday = user_birthday;
this.department_id = department_id;
}
}
2)Role.java
@Data
public class Role {
private int role_id;
private String role_name;
private List<User> users;
public Role() {
}
public Role(int role_id, String role_name) {
super();
this.role_id = role_id;
this.role_name = role_name;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
@Override
public String toString() {
return "Role [role_id=" + role_id + ", role_name=" + role_name
+ ", users=" + users + "]";
}
}
3)Department.java
@Data
public class Department {
private int department_id;
private String department_name;
private List<User> users;
public Department() {
super();
}
public Department(int department_id, String department_name,
List<User> users) {
super();
this.department_id = department_id;
this.department_name = department_name;
this.users = users;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
@Override
public String toString() {
return "Department [department_id=" + department_id
+ ", department_name=" + department_name + ", users=" + users
+ "]"+"\n";
}
}
3.实体类的 mapper 文件 1)UserDepartmentMapper.xml:多对一,多个 user 对应一个 department,使用 association
<?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="employee_management.mapper.UserDepartmentMapper">
<resultMap type="employee_management.entity.User" id="userDepartmentList">
<id property="user_id" column="user_id" javaType="java.lang.Integer" />
<result property="user_name" column="user_name" javaType="java.lang.String" />
<result property="user_gender" column="user_gender" javaType="java.lang.String" />
<result property="user_email" column="user_email" javaType="java.lang.String" />
<result property="user_phone" column="user_phone" javaType="java.lang.String" />
<result property="user_address" column="user_address" javaType="java.lang.String" />
<result property="user_birthday" column="user_birthday"
javaType="java.util.Date" />
<result property="department_id" column="department_id"
javaType="java.lang.Integer" />
<association property="department"
javaType="employee_management.entity.Department">
<id property="department_id" column="department_id" javaType="java.lang.Integer" />
<result property="department_name" column="department_name"
javaType="java.lang.String" />
</association>
</resultMap>
<select id="getAll" resultMap="userDepartmentList">
select u.*,d.department_name from user u left join department d on u.department_id=d.department_id;
</select>
</mapper>
2)UserMapper.xml:一对多,使用collection,一个user对应多个role,同时也是多对多中user这一方的一对多。如果要实现多对多,还需要完成一个role对应多个user,即完成两个一对多,写法同下。
<?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="employee_management.mapper.UserMapper">
<resultMap type="employee_management.entity.User" id="userList">
<id property="user_id" column="user_id" javaType="java.lang.Integer" />
<result property="user_name" column="user_name" javaType="java.lang.String" />
<result property="user_gender" column="user_gender" javaType="java.lang.String" />
<result property="user_email" column="user_email" javaType="java.lang.String" />
<result property="user_phone" column="user_phone" javaType="java.lang.String" />
<result property="user_address" column="user_address" javaType="java.lang.String" />
<result property="user_birthday" column="user_birthday"
javaType="java.util.Date" />
<result property="department_id" column="department_id"
javaType="java.lang.Integer" />
</resultMap>
<resultMap type="employee_management.entity.User" id="userRoleList"
extends="userList">
<collection property="roles" ofType="employee_management.entity.Role">
<id property="role_id" column="role_id" javaType="java.lang.Integer" />
<result property="role_name" column="role_name" javaType="java.lang.String" />
</collection>
</resultMap>
</resultMap>
<select id="getAll" resultMap="userList">
select * from user
</select>
<select id="getAllUserAndRole" resultMap="userRoleList">
select u.*,r.* from
user u left join user_role ur on u.user_id=ur.user_id
left join role r
on r.role_id=ur.role_id;
</select>
不管是一对多、多对一,还是多对多,只需要知道这 2 个属性哪个代表多哪个代表一,就可以很好的在实体的mapper文件中配置出来。
|