Hibernate使用——多对多关联示例

多对多关联

 

在hibernate的关联映射当中,多对多的关联映射需要借助中间表完成。由于多对多关联的性能不佳(由于引入中间表,一次读取操作需要反复数次查询),因此设计中应该避免大量使用。

 

一个例子:角色Role与权限privilege的关系是典型的一对多关系,现有一个军团,一个军团里有团长,将军,军师和士兵这几个角色,在一个军团里,团长拥有全部权限,可以任命手下,发起团战,发起讨伐Boss和日常个人训练,将军和军师除了没有任命权限,其他的都有,而士兵只有日常个人训练这一权限。。。

Hibernate使用——多对多关联示例_第1张图片
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,示例,多对多映射关联)