Hibernate的多对多关联关系
来源:互联网 发布:淘宝实木家具店 编辑:程序博客网 时间:2024/06/03 01:26
假如一个公司的组织结构发展到一定阶段,原来所定义的一个用户只属于一个部门这种需求将会发生变化,一个用户(员工)可能担任多个角色,比如,一个员工可能既是人力资源部主管、又是财务部的总监,一个人属于多个部门是再正常不过的了!那此时,一个用户可以同时多个部门,一个部门下面又有多个员工,那员工与部门之间就是一种多对多关联关系。再如,用户跟角色之间的关联关系,一个用户他可能是属于系统管理员,也可能是属于某一个项目的项目经理,也可能他是信息发布管理员等,一个用户可以同时拥有多个角色。每个角色可以有多个用户,那用户跟角色之间是一种多对多的关联关系。
下面,将以用户跟角色的关联关系来介绍一下多对多的关联关系。
物理数据模型如下图所示:
从上图我们可以看出,对于建立多对多关联关系时,我们需要建立中间表,中间表是由一个USER_ID跟一个ROLE_ID组成一个联合组件。
建表的SQL:
程序代码
/*==============================================================*/
/* DBMS name: MySQL 5.0 */
/* Created on: 2008-4-23 12:32:13 */
/*==============================================================*/
drop table if exists T_ROLE;
drop table if exists T_ROLE_USER;
drop table if exists T_USER;
/*==============================================================*/
/* Table: T_ROLE */
/*==============================================================*/
create table T_ROLE
(
ID int not null auto_increment,
ROLE_NAME VARCHAR(20) not null,
DESCRIPTION VARCHAR(255),
primary key (ID)
);
/*==============================================================*/
/* Table: T_ROLE_USER */
/*==============================================================*/
create table T_ROLE_USER
(
USER_ID INT not null,
ROLE_ID INT not null,
primary key (USER_ID, ROLE_ID)
);
/*==============================================================*/
/* Table: T_USER */
/*==============================================================*/
create table T_USER
(
ID INT not null auto_increment,
USER_NAME VARCHAR(20) not null,
LOGINID VARCHAR(20) not null,
PASSWORD VARCHAR(32) not null,
primary key (ID)
);
alter table T_ROLE_USER add constraint FK_Reference_1 foreign key (USER_ID)
references T_USER (ID) on delete restrict on update restrict;
alter table T_ROLE_USER add constraint FK_Reference_2 foreign key (ROLE_ID)
references T_ROLE (ID) on delete restrict on update restrict;
/* DBMS name: MySQL 5.0 */
/* Created on: 2008-4-23 12:32:13 */
/*==============================================================*/
drop table if exists T_ROLE;
drop table if exists T_ROLE_USER;
drop table if exists T_USER;
/*==============================================================*/
/* Table: T_ROLE */
/*==============================================================*/
create table T_ROLE
(
ID int not null auto_increment,
ROLE_NAME VARCHAR(20) not null,
DESCRIPTION VARCHAR(255),
primary key (ID)
);
/*==============================================================*/
/* Table: T_ROLE_USER */
/*==============================================================*/
create table T_ROLE_USER
(
USER_ID INT not null,
ROLE_ID INT not null,
primary key (USER_ID, ROLE_ID)
);
/*==============================================================*/
/* Table: T_USER */
/*==============================================================*/
create table T_USER
(
ID INT not null auto_increment,
USER_NAME VARCHAR(20) not null,
LOGINID VARCHAR(20) not null,
PASSWORD VARCHAR(32) not null,
primary key (ID)
);
alter table T_ROLE_USER add constraint FK_Reference_1 foreign key (USER_ID)
references T_USER (ID) on delete restrict on update restrict;
alter table T_ROLE_USER add constraint FK_Reference_2 foreign key (ROLE_ID)
references T_ROLE (ID) on delete restrict on update restrict;
初始化数据:
程序代码
insert into t_user (user_name,loginId,password) values('哲哲','zizz','admin');
insert into t_role (role_name,description) values('系统管理员','拥有系统的所有操作权限');
insert into t_role (role_name,description) values('系统管理员','拥有系统的所有操作权限');
对象模型如下图所示:
略
他们之间的关联关系为:用户对象有一个成员,成员类型是一个Set,该集合里面包含了用户所属的组。
User.java
程序代码
package zizz.model;
import java.io.Serializable;
import java.util.Set;
/**
* 该对象是针对着数据库的T_USER表.
*
* <a href="http://www.suneca.com">ZIZZ</a>
*
* Create-Time:Apr 21, 2008 9:53:58 PM
*/
public class User implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
private int id;
private String userName;
private String loginId;
private String password;
private Set<Role> roles;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
import java.io.Serializable;
import java.util.Set;
/**
* 该对象是针对着数据库的T_USER表.
*
* <a href="http://www.suneca.com">ZIZZ</a>
*
* Create-Time:Apr 21, 2008 9:53:58 PM
*/
public class User implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
private int id;
private String userName;
private String loginId;
private String password;
private Set<Role> roles;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
User.hbm.xml
程序代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="zizz.model">
<class name="User" table="T_USER">
<id name="id" column="ID">
<generator class="increment" />
</id>
<property name="userName" column="USER_NAME" />
<property name="loginId" column="LOGINID" />
<property name="password" column="PASSWORD" />
<set name="roles" inverse="false" cascade="all" lazy="true" table="T_ROLE_USER">
<key column="USER_ID"/>
<many-to-many column="ROLE_ID" class="Role"/>
</set>
</class>
</hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="zizz.model">
<class name="User" table="T_USER">
<id name="id" column="ID">
<generator class="increment" />
</id>
<property name="userName" column="USER_NAME" />
<property name="loginId" column="LOGINID" />
<property name="password" column="PASSWORD" />
<set name="roles" inverse="false" cascade="all" lazy="true" table="T_ROLE_USER">
<key column="USER_ID"/>
<many-to-many column="ROLE_ID" class="Role"/>
</set>
</class>
</hibernate-mapping>
Role.java
程序代码
package zizz.model;
import java.io.Serializable;
import java.util.Set;
/**
* 角色对象,该对象映射为数据库T_ROLE表.
*
* <a href="http://www.suneca.com">ZIZZ</a>
*
* Create-Time:Apr 23, 2008 4:19:31 PM
*/
public class Role implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
private int id;
private String roleName;
private String description;
private Set<User> users;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
import java.io.Serializable;
import java.util.Set;
/**
* 角色对象,该对象映射为数据库T_ROLE表.
*
* <a href="http://www.suneca.com">ZIZZ</a>
*
* Create-Time:Apr 23, 2008 4:19:31 PM
*/
public class Role implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
private int id;
private String roleName;
private String description;
private Set<User> users;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
Role.hbm.xml
程序代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="zizz.model">
<class name="Role" table="T_ROLE">
<id name="id" column="ID">
<generator class="increment" />
</id>
<property name="roleName" column="ROLE_NAME" />
<property name="description" column="DESCRIPTION" />
<set name="users" inverse="false" cascade="all" lazy="true" table="T_ROLE_USER">
<key column="ROLE_ID"/>
<many-to-many column="USER_ID" class="User"/>
</set>
</class>
</hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="zizz.model">
<class name="Role" table="T_ROLE">
<id name="id" column="ID">
<generator class="increment" />
</id>
<property name="roleName" column="ROLE_NAME" />
<property name="description" column="DESCRIPTION" />
<set name="users" inverse="false" cascade="all" lazy="true" table="T_ROLE_USER">
<key column="ROLE_ID"/>
<many-to-many column="USER_ID" class="User"/>
</set>
</class>
</hibernate-mapping>
假如我们的数据库T_USER表当中有一条数据,ID为1;T_ROLE当中有一条数据,ID也为1,现在我们想指派角色给用户,那我们可以使用以下的方式实现:
ManyToMany.java
程序代码
package zizz.test;
import zizz.dao.RoleDAO;
import zizz.dao.UserDAO;
import zizz.dao.hibernate.RoleDAOHibernate;
import zizz.dao.hibernate.UserDAOHibernate;
import zizz.model.Role;
import zizz.model.User;
/**
* 测试多对多.
*
* <a href="http://www.suneca.com">ZIZZ</a>
*
* Create-Time:Apr 23, 2008 4:21:53 PM
*/
public class ManyToMany {
public static void main(String[] args){
ManyToMany.assignRoleToUser();
}
public static void assignRoleToUser(){
/*因为插入T_USER、以及T_ROLE表第一条数据,id都为1*/
/* 得到角色 */
RoleDAO rdao = new RoleDAOHibernate();
Role role = rdao.findRoleById(1);
/* 得到用户 */
UserDAO udao = new UserDAOHibernate();
User user = udao.findUserById(1);
/* 将角色指派给用户 */
user.getRoles().add(role);
udao.updateUser(user);
}
}
import zizz.dao.RoleDAO;
import zizz.dao.UserDAO;
import zizz.dao.hibernate.RoleDAOHibernate;
import zizz.dao.hibernate.UserDAOHibernate;
import zizz.model.Role;
import zizz.model.User;
/**
* 测试多对多.
*
* <a href="http://www.suneca.com">ZIZZ</a>
*
* Create-Time:Apr 23, 2008 4:21:53 PM
*/
public class ManyToMany {
public static void main(String[] args){
ManyToMany.assignRoleToUser();
}
public static void assignRoleToUser(){
/*因为插入T_USER、以及T_ROLE表第一条数据,id都为1*/
/* 得到角色 */
RoleDAO rdao = new RoleDAOHibernate();
Role role = rdao.findRoleById(1);
/* 得到用户 */
UserDAO udao = new UserDAOHibernate();
User user = udao.findUserById(1);
/* 将角色指派给用户 */
user.getRoles().add(role);
udao.updateUser(user);
}
}
系统控制台打印的SQL信息:
程序代码
Hibernate: select user0_.ID as ID0_0_, user0_.USER_NAME as USER2_0_0_, user0_.LOGINID as LOGINID0_0_, user0_.PASSWORD as PASSWORD0_0_ from T_USER user0_ where user0_.ID=?
Hibernate: select roles0_.USER_ID as USER1_1_, roles0_.ROLE_ID as ROLE2_1_, role1_.ID as ID2_0_, role1_.ROLE_NAME as ROLE2_2_0_, role1_.DESCRIPTION as DESCRIPT3_2_0_ from T_ROLE_USER roles0_ left outer join T_ROLE role1_ on roles0_.ROLE_ID=role1_.ID where roles0_.USER_ID=?
Hibernate: insert into T_ROLE_USER (USER_ID, ROLE_ID) values (?, ?)
Hibernate: select roles0_.USER_ID as USER1_1_, roles0_.ROLE_ID as ROLE2_1_, role1_.ID as ID2_0_, role1_.ROLE_NAME as ROLE2_2_0_, role1_.DESCRIPTION as DESCRIPT3_2_0_ from T_ROLE_USER roles0_ left outer join T_ROLE role1_ on roles0_.ROLE_ID=role1_.ID where roles0_.USER_ID=?
Hibernate: insert into T_ROLE_USER (USER_ID, ROLE_ID) values (?, ?)
在维护多对多关联关系的时候,必须保证前后的SESSION是同一个,否则,将会出问题!将会抛出以下的错误信息:
程序代码
Exception in thread "main" org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:267)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:216)
at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:559)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:547)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:539)
at zizz.dao.hibernate.UserDAOHibernate.updateUser(UserDAOHibernate.java:53)
at zizz.test.ManyToMany.assignRoleToUser(ManyToMany.java:34)
at zizz.test.ManyToMany.main(ManyToMany.java:20)
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:267)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:216)
at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:559)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:547)
at org.hibernate.impl.SessionImpl.update(SessionImpl.java:539)
at zizz.dao.hibernate.UserDAOHibernate.updateUser(UserDAOHibernate.java:53)
at zizz.test.ManyToMany.assignRoleToUser(ManyToMany.java:34)
at zizz.test.ManyToMany.main(ManyToMany.java:20)
- Hibernate的多对多关联关系
- Hibernate,多对多的关联关系
- Hibernate的多对多关联关系
- Hibernate关联关系之一对多关联
- hibernate关联关系之多对多关系
- Hibernate -- 映射实体关联关系(多对多关联关系)
- Hibernate关联关系映射之一对多关联关系
- Hibernate关联关系映射之多对多关联关系
- Hibernate一对多、多对一关联关系的使用
- Hibernate多对多关联关系的使用
- Hibernate完成多对多的关联关系映射
- hibernate多对多关联关系
- Hibernate 映射多对多关联关系
- Hibernate 映射多对多关联关系
- Hibernate关联关系映射---多对多
- Hibernate映射多对多关联关系
- Hibernate 映射多对多关联关系
- Hibernate中关联关系:多对一的学习
- space quota exceeded for tablespace(表空间不足)
- The latest addition to PD128 V9
- 动态IP地址的捕获及其应用
- 如何写高效率的AS3代码的小技巧
- Forcal中的“关键字”
- Hibernate的多对多关联关系
- 最简单的Python singleton模式实现
- CDC异步AutoLog的简单测试
- oracle数据库文件中的导入/导出(imp/exp命令)
- C# Socket实现简单的多人聊天
- 我的手机图片站
- SQL远程映射数据库创建视图
- Treeview 只展开一个节点,其他节点关闭
- Flex中如何利用timer控制改变ViewStack当前选中Index的例子