【SSH系列】Hibernate映射 -- 一对多关联映射
? ? ? ?一對多關聯映射和多對一關聯映射的映射原理是一樣一樣的,所以說嘛,知識都是相通的,一通百通,為什么說一對多關聯映射和多對一關聯映射是一樣的呢?因為她們都是在多的一端加入一個外鍵,指向一的一段,關聯關系都是在多的一端進行維護,只是我們在寫映射的時候發生了變化。
? ? ? ?一對多和多對一的映射原理是一樣的,但是她們之間也存在著小小的區別,畢竟世界上沒有兩片完全相同的葉子,她們之間的區別就是維護的關系不同,我們先來看多對一,多端維護一端的關系,在加載多端的時候,可以將一端加載上來;一對多,一端維護多端的關系,在加載一端的時候,可以將多端加載上來。一對多關聯映射也存在兩種策略,單向和雙向,今天這篇博文,小編就來簡單的介紹一下一對多關聯映射,希望對有需要的小伙伴有幫助,不足之處,還請小伙伴們多多指教`(*∩_∩*)′。
? ? ? ?一對多單向關聯映射
? ? ? ?我們都知道,一個班級是由多個學生組成的,ok,今天的故事就從班級和學生開始拉開帷幕,我們依然從uml入手,首先我們來看對象模型,如下圖所示:
? ? ? ??
? ? ? ?從對象模型中,我們可以看出,Classes持有Student的一個引用,由于是單向關聯,所以數據在加載Classes的時候,會把Student加載上來,但是Student并不知道Classes的存在。接著,我們開始來編寫代碼的部分。
第一步、編寫實體Classes && Student,代碼如下所示,首先我們來編寫Classes,代碼如下所示:? ? ??
package com.bjpowernode.hibernate; import java.util.Set;public class Classes {private int id;private String name;private Set Students;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;}public Set getStudents() {return Students;}public void setStudents(Set students) {Students = students;} ? ? ? ? Student的代碼如下所示:
package com.bjpowernode.hibernate;public class Student {private int id;private String name;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;}} ? ? ? ? 第二步、編寫映射文件,首先編寫Classes.hbm.xml代碼如下所示:
<?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.bjpowernode.hibernate.Classes" table="t_classes"><id name="id"><generator class="native"/></id><property name="name"/><set name = "students"><key column="classesid"/><one-to-many class="com.bjpowernode.hibernate.Student"/></set></class></hibernate-mapping> ? ? ? ?接著編寫Student.hbm.xml的代碼,如下所示:
<?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.bjpowernode.hibernate.Student" table="t_student"><id name="id"><generator class="native"/></id><property name="name"/></class></hibernate-mapping> ? ? ? ?第三步、編寫hibernate.cfg.xml的代碼,建立數據庫并且添加相應的映射,代碼如下所示:
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory ><!-- MySql數據庫驅動 --><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><!-- 數據庫名稱 --> <property name="hibernate.connection.url"> jdbc:mysql:///hibernate_one2many_1</property><!-- 數據庫的用戶名 --><property name="hibernate.connection.username">root</property><!-- 數據庫的密碼 --><property name="hibernate.connection.password">123456</property><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!-- 顯示語句 --> <property name="hibernate.show_sql">true</property> <!-- 格式排版 --> <!-- <property name="hibernate.format_sql">true</property> --> <mapping resource="com/bjpowernode/hibernate/Student.hbm.xml"/> <mapping resource="com/bjpowernode/hibernate/Classes.hbm.xml"/></session-factory></hibernate-configuration> ? ? ? 接著創建數據庫,并且運行ExportDB,生成相應的表結構如下所示:
? ? ??
? ? ? 接著,我們向表里面插入數據,代碼如下所示:
package com.bjpowernode.hibernate;import java.util.HashSet;import java.util.Set;import junit.framework.TestCase;import org.hibernate.Session;public void testSave2() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Student student1 = new Student();student1.setName("張三");session.save(student1);Student student2 = new Student();student2.setName("李四");session.save(student2);Classes classes = new Classes();classes.setName("動力節點");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);}} ? ? ? ?運行代碼效果如下所示:
? ? ? ?
? ? ? ?從上面的demo實例我們可以看出來,因為多端Student不知道Classes的存在,也就是Student不維護與Classes的關系,所以在保存Student的時候,字段classesid為空,如果該字段設置為非空,則將無法保存數據;因為Student不維護關系,而Classes維護關系,Classes將會發出多余的update語句。介紹完了一對多單向關聯映射,接著我們來一起學習一下一對多雙向關聯映射,對象模型如下所示:
? ? ? ??
? ? ? 雙向關聯映射
? ? ? ? 雙向關聯映射對比單向關聯映射,對象的加載方向由單向變成了雙向。我們依然以為Classes和Student為例進行講解。
? ? ? ?第一步、編寫實體Classes && Student,代碼如下所示,首先我們來編寫Classes,代碼如下所示:
package com.bjpowernode.hibernate;import java.util.Set;public class Classes {private int id;private String name;private Set Students;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;}public Set getStudents() {return Students;}public void setStudents(Set students) {Students = students;}} ? ? ? ?接著,編寫Student的代碼,如下所示:? ? ? ?
package com.bjpowernode.hibernate;public class Student {private int id;private String name;private Classes classes;public Classes getClasses() {return classes;}public void setClasses(Classes classes) {this.classes = classes;}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;}} ? ? ? ??第二步、編寫映射文件,首先編寫Classes.hbm.xml代碼如下所示:
<?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.bjpowernode.hibernate.Classes" table="t_classes"><id name="id"><generator class="native"/></id><property name="name"/><set name = "students"><key column="classesid"/><one-to-many class="com.bjpowernode.hibernate.Student"/></set></class> ? ? ? ? 接著編寫Student.hbm.xml的代碼,如下所示:
<?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.bjpowernode.hibernate.Student" table="t_student"><id name="id"><generator class="native"/></id><property name="name"/><many-to-one name="classes" column="classesid"/></class></hibernate-mapping> ? ? ? ?第三步、編寫hibernate.cfg.xml的代碼,建立數據庫并且添加相應的映射,代碼如下所示:
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory ><!-- MySql數據庫驅動 --><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><!-- 數據庫名稱 --> <property name="hibernate.connection.url"> jdbc:mysql:///hibernate_one2many_2</property><!-- 數據庫的用戶名 --><property name="hibernate.connection.username">root</property><!-- 數據庫的密碼 --><property name="hibernate.connection.password">123456</property><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!-- 顯示語句 --> <property name="hibernate.show_sql">true</property> <!-- 格式排版 --> <!-- <property name="hibernate.format_sql">true</property> --> <mapping resource="com/bjpowernode/hibernate/Student.hbm.xml"/> <mapping resource="com/bjpowernode/hibernate/Classes.hbm.xml"/></session-factory> </hibernate-configuration> ? ? ? ?接著創建數據庫,并且運行ExportDB,生成相應的表結構如下所示:
? ? ? ?
? ? ? ?接著,我們向表里面插入數據,代碼如下所示:
package com.bjpowernode.hibernate; import java.util.HashSet; import java.util.Set; import junit.framework.TestCase; import org.hibernate.Session; public void testSave2() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Student student1 = new Student();student1.setName("張三");session.save(student1);Student student2 = new Student();student2.setName("李四");session.save(student2);Classes classes = new Classes();classes.setName("動力節點");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);}} ? ? ? ?運行代碼,效果如下所示:
? ? ? ?
? ? ? ?小編寄語:為什么多對一關聯映射不存在單向一對多中的問題呢?在多對一關聯映射里面,由于關系是在多的一端進行維護的,加載的時候從多的一端進行加載,當然沒有問題。總結一下:在多對一關聯映射中,如果用到,經常采用雙向的方式來完成映射,彌補單向加載時的問題。ok,今天的hibernate一對多映射就介紹到這里,還請小伙伴們多多指教,在下一篇博文中,小編將繼續介紹hibernate映射的相關知識,敬請期待……? ? ? ?
總結
以上是生活随笔為你收集整理的【SSH系列】Hibernate映射 -- 一对多关联映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Gartner: 2016年十大安全预测
- 下一篇: gerrit调试