Many-To-Many 例子:
创建三张表:
Person:
uid | uname |
1 | Jason |
Project:
pid | pro_name |
1 | java |
Pro_per: 关联person 和 project,表示参与了项目的人。uid 和 pid 为联合主键
pid | uid |
1 | 1 |
ManyToMany:一个人可以参加多个项目,一个项目也可以有多个人参加。
OneToMany的时候用 reverse engineering 可以生成关联的内部数据类型 Set, 但ManyToMany不会生成Set,所以要自己在类里面手写 Set,而且要在hbm.xml 里面自己手写Set 的标签。
Person.java:
package entity;
import java.util.HashSet;
import java.util.Set;
/**
* Person entity. @author MyEclipse Persistence Tools
*/
public class Person implements java.io.Serializable {
// Fields
private Integer uid;
private String uname;
private Set projects = new HashSet();
// Constructors
/** default constructor */
public Person() {
}
/** full constructor */
public Person(String uname) {
this.uname = uname;
}
// Property accessors
public Integer getUid() {
return this.uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUname() {
return this.uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Set getProjects() {
return projects;
}
public void setProjects(Set projects) {
this.projects = projects;
}
}
Project.java:
package entity;
import java.util.HashSet;
import java.util.Set;
/**
* Project entity. @author MyEclipse Persistence Tools
*/
public class Project implements java.io.Serializable {
// Fields
private Integer pid;
private String proName;
private Set Persons = new HashSet();
// Constructors
/** default constructor */
public Project() {
}
/** full constructor */
public Project(String proName) {
this.proName = proName;
}
// Property accessors
public Integer getPid() {
return this.pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getProName() {
return this.proName;
}
public void setProName(String proName) {
this.proName = proName;
}
public Set getPersons() {
return Persons;
}
public void setPersons(Set persons) {
Persons = persons;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="entity.Person" table="person" catalog="hibernate_1">
<id name="uid" type="java.lang.Integer">
<column name="uid" />
<generator class="native"></generator>
</id>
<property name="uname" type="java.lang.String">
<column name="uname" />
</property>
<strong><em><span style="color:#ff0000;"><set name = "projects" table = "pro_per">
<key column = "uid">
</key>
<many-to-many class = "entity.Project" column = "pid">
</many-to-many>
</set></span></em></strong>
</class>
</hibernate-mapping>
Project.hbm.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="entity.Project" table="project" catalog="hibernate_1">
<id name="pid" type="java.lang.Integer">
<column name="pid" />
<generator class="native"></generator>
</id>
<property name="proName" type="java.lang.String">
<column name="pro_name" />
</property>
<span style="color:#ff0000;"> <strong><set name = "persons" table = "pro_per">
<key column = "pid">
</key>
<many-to-many class = "entity.Person" column = "uid">
</many-to-many>
</set></strong></span>
</class>
</hibernate-mapping>
Test 1: 新建Person("Jason"), 从数据库读出pid=1 的project, 在person的Set 中加入该project,保存person的时候,关联关系也会自动保存到第三张表(Proj_per)里面。
package test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import sessionfactory.HibernateSessionFactory;
import entity.Person;
import entity.Project;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session s = HibernateSessionFactory.getSession();
Project pro = (Project) s.load(Project.class, 1);
Person per = new Person("Jason");
per.getProjects().add(pro);
Transaction t = s.beginTransaction();
s.save(per);
t.commit();
s.close();
}
}
生成的sql 语句:
Hibernate: insert into hibernate_1.person (uname) values (?)
Hibernate: insert into pro_per (uid, pid) values (?, ?)
在Person 和 Pro_per 两个表内都做添加。
Person (增加1-Jason):
uid | uname |
1 | Jason |
Project ( 无变化):
pid | pro_name |
1 | java |
Pro_per (增加1-1):
pid | uid |
1 | 1 |
同理,也可以load出一个person,添加到新建的一个project的set里,结果在Project 和 Pro_per 两个表里都做添加:
package test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import sessionfactory.HibernateSessionFactory;
import entity.Person;
import entity.Project;
public class Test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session s = HibernateSessionFactory.getSession();
Person per = (Person)s.load(Person.class, 4);
Project pro = new Project("iOS");
pro.getPersons().add(per);
Transaction t = s.beginTransaction();
s.save(pro);
t.commit();
s.close();
}
}
Person (无变化):
uid | uname |
... | ... |
4 | Calvin |
Project (增加2-iOS):
pid | pro_name |
1 | java |
2 | iOS |
Pro_per (增加2-4):
pid | uid |
1 | 1 |
2 | 4 |