用户表users, 中间表roles, 角色表ru
建表语句:
建表语句:
CREATE TABLE users(
u_id VARCHAR(32) PRIMARY KEY,
u_name VARCHAR(30)
);
CREATE TABLE roles(
r_id VARCHAR(32) PRIMARY KEY,
r_name VARCHAR(30)
);
CREATE TABLE ru(
ru_uid VARCHAR(32),
ru_rid VARCHAR(32),
PRIMARY KEY(ru_uid,ru_rid),
FOREIGN KEY(ru_uid) REFERENCES users(u_id),
FOREIGN KEY(ru_rid) REFERENCES roles(r_id)
);
Javabean的设计
public class User {
private String id;
private String name;
// 使用一个Set集直接映射对方
private Set<Role> roles = new HashSet<Role>();
}
public class Role {
private String id;
private String name;
// 使用一个Set集映射另一方
private Set<User> users = new HashSet<User>();
}
User.hbm.xml
<?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">
<hibernate-mapping package="cn.itcast.domain4">
<class name="cn.itcast.User" table="users">
<id name="id" type="string" length="32">
<column name="u_id"></column>
<generator class="uuid"></generator>
</id>
<property name="name" column="u_name" type="string"/>
<!-- 以下通过many-to-many映射另一方
因为在User类中,包含一个Set类型的属性,所以使用set元素。
table:是指中间表是哪一个表
key元素:是指外键,是指ru通过哪一个键与本类等值。ru.ru_uid=User.u_id
many-to-many:多对多连接哪一个类,在Set集中保存的是哪种类型
many-to-many的属性的column是指:从中间表到Role的外键是哪一个列
-->
<set name="roles" table="ru" cascade="save-update" inverse="false">
<key column="ru_uid"/> <!--通过中间表的用户id,查询该用户具有的权限-->
<many-to-many class="cn.itcast.Role" column="ru_rid"/> <!--通过课程id获取课程对象-->
</set>
</class>
</hibernate-mapping>
Role.hbm.xml
<hibernate-mapping>
<!-- 以下声明Role -->
<class name="cn.itcast.Role" table="roles">
<id name="id" type="string" length="32">
<column name="r_id"/>
<generator class="uuid"></generator>
</id>
<property name="name" column="r_name"/>
<set name="users" table="ru" inverse=”true”>
<key column="ru_rid"/>
<many-to-many class="cn.itcast.User" column="ru_uid"/>
</set>
</class>
</hibernate-mapping>
注意点:
对于双向 n-n 关联, 须把其中一端的 inverse 设置为 true, 否则可能会造成主键冲突
(如把role里的set的invers属性设置为true,表示权限表说了算)
这样设置的时候,做删除的时候,不会抛出异常,因为权限role是主控方,它说了算
如果直接删除用户user的话,会抛出异常
当设置set 的属性 cascade=”delete” 时就可以级联删除