Hibernate参考文档学习笔记——Hibernate入门(二)

“10,000小时的标准”——《异类》


今天的学习任务就是关联映射。看看Hibernate是如何处理关联关系的。

 1、创建映射类

为了说明关联关系,添加一个Person实体类,每个Person有自己对应的Event列表。

 1 public class Person {
 2     private Long id;
 3     private int age;
 4     private String firstName;
 5     private String lastname;
 6     
 7     public Person(){
 8     }
 9     
10     public Long getId() {
11         return id;
12     }
13     public void setId(Long id) {
14         this.id = id;
15     }
16 
17     public int getAge() {
18         return age;
19     }
20     public void setAge(int age) {
21         this.age = age;
22     }
23 
24     public String getFirstName() {
25         return firstName;
26     }
27     public void setFirstName(String firstName) {
28         this.firstName = firstName;
29     }
30 
31     public String getLastname() {
32         return lastname;
33     }
34     public void setLastname(String lastname) {
35         this.lastname = lastname;
36     }
37 }
View Code

创建对应的映射文件Person.hbm.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="events">
 6     <class name="Person" table="PERSON">
 7         <id name="id" column="PERSON_ID">
 8             <generator class="native" />
 9         </id>
10 
11         <property name="age" />
12         <property name="firstName" />
13         <property name="lastname" />
14     </class>
15 </hibernate-mapping>
View Code

创建好后将该映射文件添加到Hibernate.cfg.xml配置文件中。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <!-- 设置连接数据库的驱动 -->
 8         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 9         <!--  设置数据库服务器的连接路径 -->
10         <property name="connection.url">jdbc:mysql://localhost:3306/db</property>
11         <!--  设置数据库服务器的连接用户 -->
12         <property name="connection.username">root</property>
13         <!--  设置数据库服务器的连接用户的密码 -->
14         <property name="connection.password">Lynn0714</property>
15         <!-- 数据库连接池大小 -->
16         <property name="connection.pool_size">1</property>
17         <!-- SQL方言,要根据使用的数据库来配置 -->
18         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
19         <!-- 设置Hibernate的自动session管理 -->
20         <property name="current_session_context_class">thread</property>
21         <!-- 设置二级cache  -->
22         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
23         <!-- 设置运行时是否显示调用的SQL语句 -->
24         <property name="show_sql">true</property>
25         <!-- Drop and re-create the database schema on startup -->
26         <property name="hbm2ddl.auto">create</property>
27 
28         <!-- 使用的映射文件 -->
29         <mapping resource="events/Event.hbm.xml" />
30         <mapping resource="events/Person.hbm.xml"/>
31     </session-factory>
32 </hibernate-configuration>
View Code

配置好后,我们就可以开始添加关联了。

2、单向Set-based关联

对于每个Person可以参与一系列的Event,而每个Event也可能有不同的参加的Person,因此,Person和Event直接的关系如下图:

        因此需要在Person中添加一个Event集合来表示与当前人员关联的事件,同时,我们也可以在Event中添加一个Person集合来表示当前事件的所有参与者,这样我们就得到了双向映射的多对多关联。也可以采用单向的多对多关联,即只选取上述的其中一条,另一条通过一个显示查询获取结果集。在本例中,使用单向的多对多关联映射:

(1)    在Person类中添加Event集合以及对应的getter、setter

1 private Set events = new HashSet();
2 public Set getEvents() {
3     return events;
4 }
5 
6 public void setEvents(Set events) {
7     this.events = events;
8 }
9     
View Code

(2)    映射文件中添加集合映射

1 <set name="events" table="PERSON_EVENT">
2             <key column="PERSON_ID" />
3             <many-to-many column="EVENT_ID" class="Event" />
4         </set>
View Code

这样,我们就可以得到下面的表关系了

 

3、使关联工作

为了使关联工作起来,需要在EventManager中添加一些代码,

 1 private void addPersonToEvent(Long personId,Long eventId){
 2         Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 3         session.beginTransaction();
 4         
 5         Person aPerson = (Person)session.load(Person.class, personId);
 6         Event anEvent = (Event)session.load(Event.class, eventId);
 7         
 8         aPerson.getEvents().add(anEvent);
 9         
10         session.getTransaction().commit();
11     }
View Code

在这段代码中我们没有显示的使用save()或update()方法,这是因为通过load方法得到的对象都是持久化状态的,他们在事务提交的时候会自动和数据库进行同步,以此来保证数据的一致性。如果对象不是持久化状态的,那么就需要显示的调用save()或update()方法了。

4、值类型的集合

对Person实体添加一个值类型对象的集合,假如保存email地址

1     private Set emailAddresses = new HashSet();
2     
3     public Set getEmailAddresses(){
4         return emailAddresses;
5     }
6 
7     public void setEmailAddresses(Set emailAddresses){
8         this.emailAddresses = emailAddresses;
9     }
View Code

然后在映射文件中配置如下

1     <set name="emailAddresses" table="PERSON_EMAIL_ADDR">
2             <key column="PERSON_ID" />
3             <element type="string" column="EMAIL_ADDR" />
4         </set>
View Code

这次又是使用了set,但是却使用了element属性,与前面的many-to-many的不同在于,使用element并不会包含对其他实体引用的集合。

下面就把元素加入到集合中 

1 private void addEmailToPerson(Long personId, String emailAddress){
2         Session session = HibernateUtil.getSessionFactory().getCurrentSession();
3         session.beginTransaction();
4         
5         Person person = (Person)session.load(Person.class, personId);
6         person.getEmailAddresses().add(emailAddress);
7         
8         session.getTransaction().commit();
9     }
View Code

这样就可以给Person添加email了。

5、双向关联

双向关联式指让关联的两端可以相互访问,即任何一端都存有另一端的引用。前面已经将Event加入到Person中了,现在只需将Person集合加入到Event实体中即可。

1 private Set participants = new HashSet();
2     
3     public Set getParticipants(){
4         return participants;
5     }
6     
7     public void setParticipants(Set participants){
8         this.participants = participants;
9     }
View Code

Event.hbm.xml映射文件中添加对应的配置

1 <set name="participants" table="PERSON_EVENT" inverse="true">
2             <key column="EVENT_ID"/>
3             <many-to-many column="PERSON_ID" class="Person"/>
4         </set>
View Code

这里的配置与在Person.hbm.xml中的配置一样,唯一的区别在于inverse=“true”属性。

 

posted @ 2013-10-11 10:47  Forgive  阅读(973)  评论(2编辑  收藏  举报