一对多/多对一
双向的一对多/多对一关系是现实中最为常见的关联关系,即实体类A和B,一个A的实例关联多个B的实例,反过来,多个B的实例可能关联同一个A的实例,A到B的方向称为一对多,B到A的方向称为多对一。
public class A{
//A类其他属性
...
//Set集合,存储B的实例
Set bs = new HashSet();
}
public class B{
//B类其他属性
...
//A类的一个对象,表示B所关联的A的实例
A a;
}
基于主外键的一对多/多对一关联
create table person(
id int not null primary key,
name varchar(20),
age int
)
create table address(
id int not null primary key,
detail varchar(200),
zipcode varchar(10),
tel varchar(20),
type varchar(20),
person_id int,
foreign key(person_id) references person(id)
)
Person类
package onetomany;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Person implements Serializable {
private Integer id;
private String name;
private Integer age;
private Set addresses = new HashSet(0);
public Person() {
super();
}
public Person(Integer id) {
super();
this.id = id;
}
public Person(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public Person(Integer id, String name, Integer age, Set addresses) {
super();
this.id = id;
this.name = name;
this.age = age;
this.addresses = addresses;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Set getAddresses() {
return addresses;
}
public void setAddresses(Set addresses) {
this.addresses = addresses;
}
}
Person.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>
<class name="onetomany.Person" table ="person" catalog="mldn">
<id name="id" type ="java.lang.Integer">
<column name="id"/>
<generator class ="assigned"/>
</id>
<property name="name" type ="java.lang.String">
<column name="name" length="20" />
</property>
<property name="age" type ="java.lang.Integer">
<column name="age" />
</property>
<set name ="addresses" inverse="true">
<key>
<column name="person_id"/>
</key>
<one-to-many class="onetomany.Address"/>
</set>
</class>
</hibernate-mapping>
Address.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>
<class name="onetomany.Address" table ="address" catalog="mldn">
<id name="id" type ="java.lang.Integer">
<column name="id"/>
<generator class="assigned"/>
</id>
<many-to-one name="person" class="onetomany.Person" fetch ="select" cascade="all">
<column name="person_id"/>
</many-to-one>
<property name="detail" type="java.lang.String">
<column name="detail" length="200"/>
</property>
<property name="zipcode" type="java.lang.String">
<column name="zipcode" length="10"/>
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="20"/>
</property>
<property name="type" type="java.lang.String">
<column name="type" length="20"/>
</property>
</class>
</hibernate-mapping>
<mapping resource="onetomany/Person.hbm.xml" />
<mapping resource="onetomany/Address.hbm.xml" />
测试类Testonetomany.java
package test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import onetomany.Address;
import onetomany.Person;
import util.HibernateSessionFactory;
public class Testonetomany {
public static void main(String[] args) {
Person person = new Person(1,"Tom",23);
Address addr1 = new Address(10,"BeiJing","100009","010-110110","Office");
Address addr2 = new Address(11,"DaLian","116400","0411-110110","Home");
addr1.setPerson(person);
addr2.setPerson(person);
Session session = HibernateSessionFactory.getSession();
Transaction tran = session.beginTransaction();
session.save(addr1);
session.save(addr2);
tran.commit();
}
}
package test;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import onetomany.Address;
import onetomany.Person;
import util.HibernateSessionFactory;
public class Testonetomany {
Session session = HibernateSessionFactory.getSession();
Transaction tran = session.beginTransaction();
public void run(){
Person p = (Person)session.get(Person.class,1);
Set<Address> addresses = p.getAddresses();
for(Address addr:addresses){
System.out.println(addr.getDetail()+" "+addr.getType());
}
}
public static void main(String[] args) {
/*Person person = new Person(1,"Tom",23);
Address addr1 = new Address(10,"BeiJing","100009","010-110110","Office");
Address addr2 = new Address(11,"DaLian","116400","0411-110110","Home");
addr1.setPerson(person);
addr2.setPerson(person);
session.save(addr1);
session.save(addr2);
tran.commit();*/
new Testonetomany().run();
}
}
运行结果:
基于连接表的一对多/多对一关联
创建表:
create table person(
id int not null primary key,
name varchar(20),
age int
)
create table address(
id int not null primary key,
detail varchar(200),
zipcode varchar(10),
tel varchar(20),
type varchar(20),
)
create table personaddress(
personid int not null,
addressid int not null primary key
)
Person.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>
<class name="onetomany.Person" table ="person" catalog="mldn">
<id name="id" type ="java.lang.Integer">
<column name="id"/>
<generator class ="assigned"/>
</id>
<property name="name" type ="java.lang.String">
<column name="name" length="20" />
</property>
<property name="age" type ="java.lang.Integer">
<column name="age" />
</property>
<set name ="addresses" table="personaddress">
<key>
<column name="personid"/>
</key>
<one-to-many class="onetomany.Address">
<column name="addressid"/>
</one-to-many>
</set>
</class>
</hibernate-mapping>
Address.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>
<class name="onetomany.Address" table ="address" catalog="mldn">
<id name="id" type ="java.lang.Integer">
<column name="id"/>
<generator class="assigned"/>
</id>
<property name="detail" type="java.lang.String">
<column name="detail" length="200"/>
</property>
<property name="zipcode" type="java.lang.String">
<column name="zipcode" length="10"/>
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="20"/>
</property>
<property name="type" type="java.lang.String">
<column name="type" length="20"/>
</property>
<join table="personaddress">
<key>
<column name="addressid"></column>
</key>
<many-to-one name="person" cascade="all">
<column name="personid"></column>
</many-to-one>
</join>
</class>
</hibernate-mapping>
测试类
public static void main(String[] args) {
Person person = new Person(1,"Tom",23);
Address addr1 = new Address(10,"BeiJing","100009","010-110110","Office");
Address addr2 = new Address(11,"DaLian","116400","0411-110110","Home");
addr1.setPerson(person);
addr2.setPerson(person);
Session session = HibernateSessionFactory.getSession();
Transaction tran = session.beginTransaction();
session.save(addr1);
session.save(addr2);
tran.commit();
}
运行结果: