【Hibernate步步为营】--(一对多映射)之单向关联
? ? ? ?上篇文章討論了雙向關聯的一對一映射,用了兩個章節。主要是從主鍵和外鍵兩種關聯映射展開具體討論。雙向關聯的映射須要在兩個映射文件里分別加入相互的相應關系,斌剛在相應的類中加入相應的關聯類的屬性,這樣在一端載入時才干載入到還有一端的對象。
關聯中經常使用的主要有多對一、一對一、一對多和多對多。我們已經討論了兩種映射關系,接下來將會討論一對多的關系。
一、單向一對多
前篇文章中以前對多對一的關系展開了討論。當中主要使用的是<many-to-one>的關系,在多的一端維護一的一端,那和今天要討論的一對多的關系它們之間是否有關聯呢?在關系和對象模型中存在了一對多關系所以理所當然就會有多對一的關系,Hibernate相同提供了一對多關系的標簽<one-to-many>。 一對多關系的對象模型在日常生活中也常常看到,就拿學生和班級來說,一個班級里有多個學生,所以班級和學生的關系是一對多的關系,映射到對象模型中,例如以下圖:
對象模型說明了這樣的一對多的關系是由一的一端來維護的,那么映射成關系模型就是一個班級字段以下會有多個學生,這樣就形成了一對多的關系。通過班級可以查詢獲得學生信息。相應的關系模型例如以下圖:
? 1、基本配置
有了對象模型接下來就讓它們映射為相應的關系代碼,在進行關系映射時須要在一的一端加入<one-to-many>標簽,另外還須要在一的一端加入Set屬性。它支持延遲載入,然后在映射文件加入set標簽,并指明一對多的關系,這樣就行在一的一端查詢獲取多的一端。
Classes類及映射文件 它是模型中最重要的一端。在該端須要加入相應的set屬性。并在配置文件里加入set標簽,在set標簽中配置相應的<one-to-many>對象,詳細Classes.java對象代碼例如以下: <pre name="code" class="java">package com.src.hibernate;import java.util.Set;public class Classes {private int id;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;}private String name;//Set支持延遲載入private Set students;public Set getStudents() {return students;}public void setStudents(Set students) {this.students = students;} } ? ? ? Classes對象中使用了set屬性,可是僅僅是說明了延遲載入的屬性。并沒有為屬性配置相應的對象,屬性的對象是要在映射文件里來配置的。須要加入set標簽,并在set標簽中加入<one-to-many>標簽,詳細例如以下代碼: <?
xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.hibernate.Classes" table="t_classes"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="students"> <key column="classesid"></key> <one-to-many class="com.hibernate.Student"></one-to-many> </set> </class> </hibernate-mapping>
? ? ? ? 相應的Student對象中的代碼和映射文件不須要什么特殊的配置,僅僅須要依照通常的寫法編寫就可以。詳細的配置方法不再詳述。非常easy。配置好后須要生成相應的SQL語句,將對象模型轉化為關系模型時Hibernate生成相應的語句例如以下: alter table t_student drop foreign key FK4B9075705E0AFEFE drop table if exists t_classes drop table if exists t_student create table t_classes (id integer not null auto_increment, name varchar(255), primary key (id)) create table t_student (id integer not null auto_increment, name varchar(255), classesid integer, primary key (id)) alter table t_student add index FK4B9075705E0AFEFE (classesid), add constraint FK4B9075705E0AFEFE foreign key (classesid) references t_classes (id)
? ? ? 生成的相應的關系模型例如以下圖:
對照SQL語句和關系模型。對應的表之間的關聯是通過外鍵來維護的,首先是創建兩張表,并指定表的主鍵。最后加入一對多的外鍵關聯關系。
? 2、基本操作
在對數據庫的操作無非是讀和寫兩種。改動也屬于寫的一種,接下來看看是怎樣向數據庫中寫入和讀取操作的。寫入數據 寫入數據須要注意的是一對多的關系,所以在加入的時候須要加入多個學生類,另外因為在classes中加入了相應的set屬性,所以在加入Student對象時應該使用HashSet來加入,這樣既可實現一對多的關系,詳細例如以下代碼: public void testSave2(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();Student student1=new Student();student1.setName("zhangsan");session.save(student1);Student student2=new Student();student2.setName("lisi");session.save(student2);Classes classes=new Classes();classes.setName("ClassOne");Set students=new HashSet();students.add(student1);students.add(student2);classes.setStudents(students);//能夠成功保存數據//可是會發出多余的update語句來維持關系。由于是一對多的原因session.save(classes);session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);} }
? ? ? ? 那么執行上面的測試用例生成的相應的數據寫入到數據庫中后例如以下圖:
?讀取數據 寫入操作相對簡單,僅僅須要把全部載入的對象都加入到Transient狀態下,執行相應的方法就能夠插入內容,可是相應的讀取操作就會略微復雜點,由于須要迭代獲取全部的學生對象,所以這樣的一對多的關系效率并不非常高。詳細代碼例如以下: package com.test.hibernate;import java.util.Iterator; import java.util.Set; import com.src.hibernate.*; import junit.framework.TestCase; import org.hibernate.Session;public class One2ManyTest extends TestCase {public void testLoad1(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();//獲取主鍵為5的班級信息Classes classes=(Classes)session.load(Classes.class,5);//打印班級信息System.out.println("classes.name="+classes.getName());//設置學生集合。通過班級載入學生集合Set students=classes.getStudents();//迭代集合,打印集合中學生的信息for(Iterator iter=students.iterator();iter.hasNext();){Student student=(Student)iter.next();System.out.println("student.name="+student.getName());}session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}} }
? ? ? 生成的對應的語句及信息例如以下語句: Hibernate: select classes0_.id as id1_0_, classes0_.name as name1_0_ from t_classes classes0_ where classes0_.id=?
classes.name=ClassOne Hibernate: select students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id0_0_, students0_.name as name0_0_ from t_student students0_ where students0_.classesid=?
student.name=lisi student.name=zhangsan
結語
一對多的關系也是經經常使用到的,可是這樣的關系在載入時效率會不高。由于須要維護的數據較多,所以不建議使用一對多的關系,能夠考慮多對一的關系,這樣在載入時事實上是一種一對一的關系,載入的效率較高,關系和對象模型得到了優化。這里僅僅是討論了單向的一對多,下篇文章討論雙向的關聯關系。
轉載于:https://www.cnblogs.com/jhcelue/p/6971865.html
總結
以上是生活随笔為你收集整理的【Hibernate步步为营】--(一对多映射)之单向关联的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 3.0内置函数map、fi
- 下一篇: 关于Linux 是怎么来的,该如何去学