多对多关联
在hibernate的关联映射当中,多对多的关联映射需要借助中间表完成。由于多对多关联的性能不佳(由于引入中间表,一次读取操作需要反复数次查询),因此设计中应该避免大量使用。
一个例子:角色Role与权限privilege的关系是典型的一对多关系,现有一个军团,一个军团里有团长,将军,军师和士兵这几个角色,在一个军团里,团长拥有全部权限,可以任命手下,发起团战,发起讨伐Boss和日常个人训练,将军和军师除了没有任命权限,其他的都有,而士兵只有日常个人训练这一权限。。。
TRole.java
package learnHibernate.bean; import java.io.Serializable; import java.util.HashSet; import java.util.Set; public class TRole implements Serializable{ private static final long serialVersionUID = -2404169291623739243L; private int id; private String name; private Set<TPrivilege> privileges = new HashSet<TPrivilege>(); public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<TPrivilege> getPrivileges() { return privileges; } public void setPrivileges(Set<TPrivilege> privileges) { this.privileges = privileges; } }
TRole.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="learnHibernate.bean"> <class name="TRole" table="t_role"> <id name="id" column="id" type="java.lang.Integer"> <generator class="native"/> </id> <property name="name" column="name" type="java.lang.String"/> <set name="privileges" table="t_role_privilege" lazy="false" cascade="save-update"> <key column="rid"/> <many-to-many class="TPrivilege" column="pid"/> </set> </class> </hibernate-mapping>
TPrivilege.java
package learnHibernate.bean; import java.io.Serializable; import java.util.HashSet; import java.util.Set; public class TPrivilege implements Serializable{ private static final long serialVersionUID = -5315523735464709855L; private int id; private String name; private Set<TRole> roles = new HashSet<TRole>(); public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<TRole> getRoles() { return roles; } public void setRoles(Set<TRole> roles) { this.roles = roles; } }
TPrivilege.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="learnHibernate.bean"> <class name="TPrivilege" table="t_privilege"> <id name="id" column="id" type="java.lang.Integer"> <generator class="native"/> </id> <property name="name" column="name" type="java.lang.String"/> <set name="roles" table="t_role_privilege" lazy="false" inverse="true" cascade="save-update"> <key column="pid"/> <many-to-many class="TRole" column="rid"/> </set> </class> </hibernate-mapping>
注意映射文件中,cascade设置为“save-update”,是因为对于多对多的逻辑而言,很少出现删除一方需要级联删除所有关联数据的情况,如删除一个“团长”角色,不会删除其包含的所有权限,同样,删除一个权限,不会删除与之关联的所有角色。
多对多的两方不能都是主控方,也就是说,要在其中的一个映射配置中设置inverse为true。没有主控方也不行,因为那样hibernate不会插中间表。
执行代码:
TRole r1 = new TRole(); r1.setName("Regimental commander"); TRole r2 = new TRole(); r2.setName("General"); TRole r3 = new TRole(); r3.setName("Military adviser"); TRole r4 = new TRole(); r4.setName("Private"); TPrivilege p1 = new TPrivilege(); p1.setName("Assignment"); TPrivilege p2 = new TPrivilege(); p2.setName("Expedition"); TPrivilege p3 = new TPrivilege(); p3.setName("Trainning"); r1.getPrivileges().add(p1); r1.getPrivileges().add(p2); r1.getPrivileges().add(p3); r2.getPrivileges().add(p2); r2.getPrivileges().add(p3); r3.getPrivileges().add(p2); r3.getPrivileges().add(p3); r4.getPrivileges().add(p3); p1.getRoles().add(r1); p2.getRoles().add(r1); p2.getRoles().add(r2); p2.getRoles().add(r3); p3.getRoles().add(r1); p3.getRoles().add(r2); p3.getRoles().add(r3); p3.getRoles().add(r4); SessionFactory factory = HibernateLocalUtil.getSessionFactory(); Session session = factory.openSession(); Transaction tx = session.beginTransaction(); //多对多关联必须同时对关联双方进行保存 session.save(r1); session.save(r2); session.save(r3); session.save(r4); session.save(p1); session.save(p2); session.save(p3); tx.commit(); session.close();
输出sql:
Hibernate: insert into t_role (name) values (?) Hibernate: insert into t_privilege (name) values (?) Hibernate: insert into t_role (name) values (?) Hibernate: insert into t_privilege (name) values (?) Hibernate: insert into t_role (name) values (?) Hibernate: insert into t_role (name) values (?) Hibernate: insert into t_privilege (name) values (?)
相关推荐
Hibernate 4——Hello World
NULL 博文链接:https://gwoham-163-com.iteye.com/blog/1895101
NULL 博文链接:https://gwoham-163-com.iteye.com/blog/1885253
Hibernate 多对一外键单向关联 Hibernate 多对一连接表单向关联 Hibernate 多对多单向关联 Hibernate 一对一外键双向关联 Hibernate 一对一主键双向关联 Hibernate 一对一连接表双向关联 Hibernate 一对多外键双向...
简单的Hibernate实现Java通过多对多关联映射,进行学生课程管理。
Hibernate多对多关联添加及查询示例
这里包含了hibernate多对一单向关联关系实现源码,希望对你有用。
hibernate一对多双项自身关联关系示例 带数据库ddl
多对多双向关联 <br>注意映射规则: <set name="roles" table="t_user_role"><br> <key column="userid"/><br> <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/> </set><br> table...
Hibernate一对多使用非主键关联设置,参看详细说明
Hibernate学习:单向多对一关联 工程
hibernate外键实现一对一双向关联关系源码
hibernate主键实现一对一单向关联关系源码
NULL 博文链接:https://1028826685.iteye.com/blog/1536060
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
Hibernate映射一对多关联关系
hibernate外键实现一对一单向关联关系源码
NULL 博文链接:https://dreamzhong.iteye.com/blog/1200915