Hibernate建立双向一对多的步骤
在我们的应用中一对多的关系是处处可见的,在数据库中通常的做法是在“多”的一端持有“一”的那一端的一个唯一标识字段(通常是主键)。但是在面向对象的设计中,一般是建立两者的关联,而不是通过引用属性来表示这种关系,关联具有更丰富的语义。
生成的相关代码:People.java
package net.wide.pojo;
import java.util.Set;
public class People { private int pid; //people id private String name; //people name private Set emails; public Set getEmails() { return emails; } public void setEmails(Set emails) { this.emails = emails; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } } |
Email.java
package net.wide.pojo;
public class Email { private int mid; private String mail; private People people; public People getPeople() { return people; } public void setPeople(People people) { this.people = people; } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } public int getMid() { return mid; } public void setMid(int mid) { this.mid = mid; } } |
建表脚本(SQL SERVER)
CREATE TABLE PEOPLE( |
把对象跟关系数据库建立映射,则是通过映射文件来完成的。手工分四步来完成映射:
1. 首先不考虑对象之间的关系,只是把单个对象跟关系数据库建立映射。
2. 确定映射关系,补全关联映射的框架,下面详述。
3. 抛开对象,专注于建立他们的关联,因为这个关联则更接近数据库中的表之间的关联。
4. 调整一下参数,优化一下。
我发现这样思路很清晰,以前觉得建立关联是很痛苦的事情,用工具来完成常常会生成非常多的垃圾代码。
现在开始第一步,People.hbm.xml
<hibernate-mapping package="net.wide.pojo"> <class table="PEOPLE" name="People"> <id name="pid" type="int" column="PID"> <generator class="assigned"/> </id> <property name="name" column="NAME" type="string" not-null="true"/> </class> </hibernate-mapping> |
Email.hbm.xml
<hibernate-mapping package="net.wide.pojo"> <class name="Email" table="EMAIL"> <id name="mid" column="MID" type="int"> <generator class="assigned"/> </id> <property name="mail" column="MAIL" type="string" not-null="true"/> </class> </hibernate-mapping> |
这样就建立了单个对象到关系数据库的映射,现在开始第二步,补全关联关系的大体框架。
我们确定了使用多对一的双向关联,People一端是“一”的一端,与之关联的多的一端是类是net.wide.pojo.Email,因此在People.hbm.xml中加上下面的一段
<set name="emails" cascade="all" inverse="true"> <key column="?"/> <one-to-many class="net.wide.pojo.Email"/> </set> |
在Email.hbm.xml中加上
<many-to-one column="?" class="net.wide.pojo.People" name="people"/> |
现在抛开对象,来看看这两个表之间该如何关联。在表People中要取得一个people的所有email就必须用主键PID跟email表中的MPID关联,反之要想知道某个email属于谁,也是通过MPID与PID关联。<key column="?"/>中的column正是引用自EMAIL中与记录关联的字段,反过来many-to-one也是通过MPID来建立关联的。“?”处填入MPID。
最后可以来调整参数优化。
public void testInsert()throws Exception{ Session session = SessionManager.currentSession(); People people = new People(); Set emails = new HashSet(); Email email1 = new Email(); Email email2 = new Email(); email1.setMid(100); email1.setMail("lyw@yahoo.com"); email2.setMid(101); email2.setMail("lyw@163.com");
people.setPid(1); people.setName("lyw");
email1.setPeople(people); email2.setPeople(people); emails.add(email1); emails.add(email2); people.setEmails(emails); Transaction transaction = session.beginTransaction(); session.save(people); transaction.commit(); } |