四个表:用户表,角色表,(中间表)角色和权限,权限表
用户表关联角色表中从角色表出发是(一对多)关系
用户表关联角色表中从用户表出发是(多对一)关系
sys_role角色表(主表)
sys_user用户表(从表)
2.Role实体类
package com.zking.crm.entity;
import java.io.Serializable;
import java.util.Set;
public class Role implements Serializable{
private Integer id;
private String name;
private String desc;
private Integer flag;
//Role和User之间是一对多的关系,所有这里要用集合
private Set<User> userSet; //从表
private Set<Right> rightSet;
public Set<Right> getRightSet() {
return rightSet;
}
public void setRightSet(Set<Right> rightSet) {
this.rightSet = rightSet;
}
public Set<User> getUserSet() {
return userSet;
}
public void setUserSet(Set<User> userSet) {
this.userSet = userSet;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
@Override
public String toString() {
return "Role [id=" + id + ", name=" + name + ", desc=" + desc + ", flag=" + flag + "]";
}
public Role() {
}
}
2.1Role映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 映射文件 -->
<!-- java类与数据表之间对应关系 -->
<hibernate-mapping package="com.zking.crm.entity">
<!-- name="User类" table:"数据库的表名称" -->
<class name="Role" table="sys_role">
<!-- id主键列 -->
<id name="id" column="role_id">
<!-- 主键生成策略
由数据库生成的策略有:mysql:increment sql server:identified oracle:序列
以上方式可以使用:native
主键不是自增长,由程序指定: assigned -->
<generator class="native"/>
</id>
<!-- property普通列 -->
<property name="name" type="java.lang.String" column="role_name"/>
<property name="desc" type="java.lang.String" column="role_desc"/>
<property name="flag" type="java.lang.Integer" column="role_flag"/>
<!-- 一对多的关系 -->
<set name="userSet">
<!-- 指定外键列 -->
<key column="usr_role_id"></key>
<one-to-many class="com.zking.crm.entity.User"/>
</set>
<!-- 多对多的关系 -->
<!-- table="sys_role_right":中间表 cascade="":设置级联行为,包括增删改-->
<set name="rightSet" table="sys_role_right" cascade="">
<!-- 中间表与当前表的Role类的外键列的关系 -->
<key column="rf_role_id"></key>
<!--
class="com.zking.crm.entity.Right":指定要关联的类
-->
<many-to-many class="com.zking.crm.entity.Right" column="rf_right_code"></many-to-many>
</set>
</class>
</hibernate-mapping>
1.User实体类
package com.zking.crm.entity;
import java.io.Serializable;
public class User implements Serializable{
//可序列化
private static final long serialVersionUID = 738335684472610303L;
private Integer id;
private String name;
private String password;
private Integer roleId;
private Integer flag;
//User和Role是多对一的关系
//1.添加一方的实体对象,多对一的对象
private Role role; //主表
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + ", roleId=" + roleId + ", flag=" + flag
+ "]";
}
public User() {
}
}
1.2User的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- java类与数据表之间对应关系 -->
<hibernate-mapping package="com.zking.crm.entity">
<!-- name="User类" table:"数据库的表名称" -->
<class name="User" table="sys_user">
<!-- id主键列 -->
<id name="id" column="usr_id">
<!-- 主键生成策略
由数据库生成的策略有:mysql:increment sql server:identified oracle:序列
以上方式可以使用:native
主键不是自增长,由程序指定: assigned -->
<generator class="native"/>
</id>
<!-- property普通列 -->
<property name="name" type="java.lang.String" column="usr_name"/>
<property name="password" type="java.lang.String" column="usr_password"/>
<!-- <property name="roleId" type="java.lang.Integer" column="usr_role_id"/> -->
<!-- 外键列的属性
name:是User类中的属性名
class:是属性对应的类型
column:主键表的外键列
多对一的关系
-->
<many-to-one name="role" class="com.zking.crm.entity.Role" column="usr_role_id"></many-to-one>
</class>
</hibernate-mapping>
3.测试
package com.zking.test2;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.zking.crm.entity.Right;
import com.zking.crm.entity.Role;
import com.zking.crm.entity.User;
import com.zking.crm.util.HibernateUtil;
public class AssociationTest {
/**
* 多对一
* 一:建立多对一的关系
* 1.在多的一方User类中添加一的一方Role对象
* 2.在User.hbm.xml映射文件中添加many-to-one配置
*/
/**
* 建立多对一的关联
* User对Role
* 级联查询
* 1.级联查询策略:采用懒加载的策略 而不是立即加载
* 2.
*/
@Test
public void assocQueryManyToOne() {
Session session = HibernateUtil.getSession();
User user = session.get(User.class, 2);
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(user.getRole());
session.close();
System.out.println(user);
System.out.println(user.getRole());
}
/**
* 建立一对多的关联
* Role对User
* 1.在一方Role中添加多方Set集合
* 2.在一方Role.hbm.xml映射文件<set>配置
*/
@Test
public void assocQueryOneToMany() {
Session session = HibernateUtil.getSession();
Role role = session.get(Role.class, 1);
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(role.getUserSet());
session.close();
System.out.println(role);
System.out.println(role.getUserSet());
}
/**
* 建立Role与Right之间的多对多
*/
@Test
public void assocQueryManyToMany() {
Session session = HibernateUtil.getSession();
Role role = session.get(Role.class, 3);
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(role.getRightSet());
session.close();
System.out.println(role);
System.out.println(role.getRightSet());
}
/**
* 建立Right与Role之间的多对多
*/
@Test
public void assocQueryManyToMany2() {
Session session = HibernateUtil.getSession();
Right right = session.get(Right.class, "L01");
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(right.getRoleSet());
session.close();
System.out.println(right);
System.out.println(right.getRoleSet());
}
/**
* 怎么为某个Role分配一个已存在的Right
*/
@Test
public void testAssignedRight() {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Role role = session.get(Role.class, 3);
//新权限:L02
Right right = session.get(Right.class, "L02");
//当前Role拥有的权限
Set<Right> rightSet = role.getRightSet();
//将新权限添加到rightSet集合中,建立了Role与Right之间关联关系
rightSet.add(right);
//建立Rigth与Role之间关联关系
// right.getRoleSet().add(role);//由于Right.hbm.xml中inverse="true",所以可以省略
session.update(role);
tx.commit();
session.close();
}
/**
* 某个角色移除已拥有的权限
*/
@Test
public void testAssignedRight2() {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Role role = session.get(Role.class, 3);
//当前Role拥有的权限
Set<Right> rightSet = role.getRightSet();
Right right = session.get(Right.class, "L02");
rightSet.remove(right);
session.update(role);
tx.commit();
session.close();
}
}
测试运行结果
User对Role 多对一
Role对Role 一对多
Role对Right 一对多
多对多
sys_role角色表(没有外键列)
sys_right权限表(没有外键列)
sys_role_right中间表
角色表关联权限表中从角色表出发是(一对多)关系(一个角色会对应多个权限)
角色表关联权限表中从权限表出发是(一对多)关系(一个权限会对应多个角色)
所以他们之间的关系是多对多的关系,因为两个表里面都没有外键列,所以会通过一个中间表来维护之间的关系
重点:想要维护多对多之间的关系,就一定要引入一张中间表,但是在实体类中是没有中间表的实体类
Role实体类
package com.zking.crm.entity;
import java.io.Serializable;
import java.util.Set;
public class Role implements Serializable{
private Integer id;
private String name;
private String desc;
private Integer flag;
//Role和User之间是一对多的关系,所有这里要用集合
private Set<User> userSet;
private Set<Right> rightSet;//Role和Right之间是一对多的关系,所有这里要用集合
public Set<Right> getRightSet() {
return rightSet;
}
public void setRightSet(Set<Right> rightSet) {
this.rightSet = rightSet;
}
public Set<User> getUserSet() {
return userSet;
}
public void setUserSet(Set<User> userSet) {
this.userSet = userSet;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
@Override
public String toString() {
return "Role [id=" + id + ", name=" + name + ", desc=" + desc + ", flag=" + flag + "]";
}
public Role() {
}
}
Role的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 映射文件 -->
<!-- java类与数据表之间对应关系 -->
<hibernate-mapping package="com.zking.crm.entity">
<!-- name="User类" table:"数据库的表名称" -->
<class name="Role" table="sys_role">
<!-- id主键列 -->
<id name="id" column="role_id">
<!-- 主键生成策略
由数据库生成的策略有:mysql:increment sql server:identified oracle:序列
以上方式可以使用:native
主键不是自增长,由程序指定: assigned -->
<generator class="native"/>
</id>
<!-- property普通列 -->
<property name="name" type="java.lang.String" column="role_name"/>
<property name="desc" type="java.lang.String" column="role_desc"/>
<property name="flag" type="java.lang.Integer" column="role_flag"/>
<!-- 一对多的关系 -->
<set name="userSet">
<!-- 指定外键列 -->
<key column="usr_role_id"></key>
<one-to-many class="com.zking.crm.entity.User"/>
</set>
<!-- 多对多的关系 -->
<!-- table="sys_role_right":中间表 cascade="":设置级联行为,包括增删改-->
<set name="rightSet" table="sys_role_right" cascade="">
<!-- 中间表与当前表的Role类的外键列的关系 -->
<key column="rf_role_id"></key>
<!--
class="com.zking.crm.entity.Right":指定要关联的类
-->
<many-to-many class="com.zking.crm.entity.Right" column="rf_right_code"></many-to-many>
</set>
</class>
</hibernate-mapping>
Right实体类
package com.zking.crm.entity;
import java.util.Set;
/**
* 权限类
* @author zjjt
*
*/
public class Right {
private String code;
private String text;
//Right与Role(一对多)多对多关联
private Set<Role> roleSet;
public Set<Role> getRoleSet() {
return roleSet;
}
public void setRoleSet(Set<Role> roleSet) {
this.roleSet = roleSet;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "Right [code=" + code + ", text=" + text + "]";
}
}
Right的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 映射文件 -->
<!-- java类与数据表之间对应关系 -->
<hibernate-mapping package="com.zking.crm.entity">
<!-- name="User类" table:"数据库的表名称" -->
<class name="Right" table="sys_right">
<!-- id主键列 -->
<id name="code" column="right_code">
<!-- 主键生成策略
由数据库生成的策略有:mysql:increment sql server:identified oracle:序列
以上方式可以使用:native
主键不是自增长,由程序指定: assigned -->
<!-- 主键是String类型,所有应用程序指定 -->
<generator class="assigned"/>
</id>
<!-- property普通列 -->
<property name="text" type="java.lang.String" column="right_text"/>
<!-- 多对多的关系
table:指定中间表的名称
inverse="true":将关系维护交给多方Role
-->
<set name="roleSet" table="sys_role_right" inverse="true">
<!-- 指定外键列 column:当前表与中间表的关系外键列-->
<key column="rf_right_code"></key>
<many-to-many class="com.zking.crm.entity.Role" column="rf_role_id"/>
</set>
</class>
</hibernate-mapping>
测试
/**
* 建立一对多的关联
* Role对User
* 1.在一方Role中添加多方Set集合
* 2.在一方Role.hbm.xml映射文件<set>配置
*/
@Test
public void assocQueryOneToMany() {
Session session = HibernateUtil.getSession();
Role role = session.get(Role.class, 1);
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(role.getUserSet());
session.close();
System.out.println(role);
System.out.println(role.getUserSet());
}
/**
* 建立Role与Right之间的多对多
*/
@Test
public void assocQueryManyToMany() {
Session session = HibernateUtil.getSession();
Role role = session.get(Role.class, 3);
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(role.getRightSet());
session.close();
System.out.println(role);
System.out.println(role.getRightSet());
}
/**
* 建立Right与Role之间的多对多
*/
@Test
public void assocQueryManyToMany2() {
Session session = HibernateUtil.getSession();
Right right = session.get(Right.class, "L01");
//initialize使得Hibernate立即去查询级联对象
Hibernate.initialize(right.getRoleSet());
session.close();
System.out.println(right);
System.out.println(right.getRoleSet());
}
/**
* 怎么为某个Role分配一个已存在的Right
*/
@Test
public void testAssignedRight() {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Role role = session.get(Role.class, 3);
//新权限:L02
Right right = session.get(Right.class, "L02");
//当前Role拥有的权限
Set<Right> rightSet = role.getRightSet();
//将新权限添加到rightSet集合中,建立了Role与Right之间关联关系
rightSet.add(right);
//建立Rigth与Role之间关联关系
// right.getRoleSet().add(role);//由于Right.hbm.xml中inverse="true",所以可以省略
session.update(role);
tx.commit();
session.close();
}
/**
* 某个角色移除已拥有的权限
*/
@Test
public void testAssignedRight2() {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Role role = session.get(Role.class, 3);
//当前Role拥有的权限
Set<Right> rightSet = role.getRightSet();
Right right = session.get(Right.class, "L02");
rightSet.remove(right);
session.update(role);
tx.commit();
session.close();
}
运行结果
Role对Right 一对多
Right对Role 一对多