一、多对多关系映射中示例
1、以用户和角色之间的关系为例
二、明确两张表关系
1、一个用户有多个角色
2、一个角色可以赋予多个用户
三、数据库中建立表关系
1、实现多对多关系,需要靠中间表
四、实体类中描述出实体之间的关系
1、用户可以具有多个角色:用户实体中包含一个角色实体的集合引用。
/**
* 一个用户的实体类
* @author zhy
*
*/
@Entity
@Table(name="sys_user")
public class SysUser implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="user_id")
private Long userId;
@Column(name="user_name")
private String userName;
@Column(name="user_password")
private String userPassword;
@Column(name="user_state")
private String userState;
//一个用户可以包含多个角色
private Set<SysRole> roles = new HashSet<SysRole>(0);
2、角色可以赋予多个用户:角色实体中包含一个用户视图的集合引用。
/**
* 一个角色的实体
* @author zhy
*
*/
@Entity
@Table(name="sys_role")
public class SysRole implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="role_id")
private Long roleId;
@Column(name="role_name")
private String roleName;
@Column(name="role_memo")
private String roleMemo;
//一个角色可以赋予多个用户
private Set<SysUser> users = new HashSet<SysUser>(0);
五、配置映射中体现两个实体之间的关系
1、用户实体中的映射
(1)、JPA注解方式
//一个用户可以包含多个角色
@ManyToMany(mappedBy="users",cascade=CascadeType.ALL)//PERSIST(持久化) persistence的动词。
private Set<SysRole> roles = new HashSet<SysRole>(0);
(2)、XML方式映射
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.domain">
<class name="SysUser" table="sys_user">
<id name="userId" column="user_id">
<generator class="native"></generator>
</id>
<property name="userName" column="user_name"></property>
<property name="userPassword" column="user_password"></property>
<property name="userState" column="user_state"></property>
<!-- 多对多关系映射
涉及的标签:
set:用于映射集合属性
属性:
name:指定集合属性的名称
table:指定的是中间表的名称,在多对多的配置时,必须写。
key:指定外键字段
属性:
column:指定的是当前映射文件所对应的实体在中间表的外键字段名称
many-to-many:指定当前映射文件所对应的实体和集合元素所对应的实体是多对多的关系
属性:
class:指定集合元素所对应的实体类
column:指定的是集合元素所对应的实体在中间表的外键字段名称
-->
<set name="roles" table="user_role_rel">
<key column="user_id"></key>
<many-to-many class="SysRole" column="role_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
2、角色实体中的映射
(1)、JPA注解方式
//一个角色可以赋予多个用户
@ManyToMany(cascade=CascadeType.ALL)
//@JoinTable:加入一个新的表 name="user_role_rel":表名
//name ==> 中间表的名称
//joinColumns ==> 添加一个当前实体在中间表中的字段
// JoinColumn(name="rel_role_id" ==> 当前实体类在中间表中的主键字段
//referencedColumnName="role_id") ==> 当前实体在对应表中的主键字段
//inverseJoinColumns ==> 添加一个对方实体在中间表中的字段
@JoinTable(name="user_role_rel",
joinColumns={@JoinColumn(name="rel_role_id",referencedColumnName="role_id")},
inverseJoinColumns={@JoinColumn(name="rel_user_id",referencedColumnName="user_id")}
)
private Set<SysUser> users = new HashSet<SysUser>(0);
(2)、XML方式
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.domain">
<class name="SysRole" table="sys_role">
<id name="roleId" column="role_id">
<generator class="native"></generator>
</id>
<property name="roleName" column="role_name"></property>
<property name="roleMemo" column="role_memo"></property>
<!-- 多对多关系映射 -->
<set name="users" table="user_role_rel">
<key column="role_id"></key>
<many-to-many class="SysUser" column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
六、测试多对多关联关系的操作
1、保存
/**
* 保存操作:
* 需求
* 1、创建2个用户
* 2、创建3个角色
* 3、让1号用户具备1,2号角色
* 4、让2号用户具备2,3号角色
* 5、保存用户和角色
*/
@Test
public void test1(){
SysUser u1 = new SysUser();
u1.setUserName("user1");
SysUser u2 = new SysUser();
u2.setUserName("user2");
SysRole r1 = new SysRole();
r1.setRoleName("角色1");
SysRole r2 = new SysRole();
r2.setRoleName("角色2");
SysRole r3 = new SysRole();
r3.setRoleName("角色3");
//建立用户角色的关联关系
u1.getRoles().add(r1);
r1.getUsers().add(u1);
u1.getRoles().add(r2);
r2.getUsers().add(u1);
u2.getRoles().add(r2);
u2.getRoles().add(r3);
r2.getUsers().add(u2);
r3.getUsers().add(u2);
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
s.save(u1);
// s.save(u2);
// s.save(r1);
// s.save(r2);
// s.save(r3);
tx.commit();
}
2、删除 -- 多对多关系中禁止使用级联删除
/**
* 删除操作
*
* 在多对多操作,级联删除,禁用
*/
@Test
public void test2(){
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
SysUser u1 = s.get(SysUser.class, 1L);
s.delete(u1);
tx.commit();
}