Hibernate学习4—关联关系一对多映射2
Class.hbm.xml:
<hibernate-mapping package="com.cy.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="identity"></generator></id><property name="name" column="className"></property><set name="students" cascade="save-update"><!-- key外鍵,column是對(duì)應(yīng)Student表的外鍵classId 就是many-to-one中的column;--><key column="classId"></key><!-- class就是students屬性,對(duì)應(yīng)的集合中裝的類Student --><one-to-many class="com.cy.model.Student"/></set></class> </hibernate-mapping>com.cy.model.Student還和之前一樣:
package com.cy.model;public class Student {private long id;private String name;private Class c;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Class getC() {return c;}public void setC(Class c) {this.c = c;}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + "]";}} View CodeStudent.hbm.xml還和之前一樣:
<hibernate-mapping package="com.cy.model"><class name="Student" table="t_student"><id name="id" column="stuId"><generator class="identity"></generator></id><property name="name" column="stuName"></property><many-to-one name="c" column="classId" class="com.cy.model.Class" cascade="save-update"></many-to-one></class> </hibernate-mapping> View Code測試代碼StudentTest:
@Testpublic void testSaveClassAndStudent() {Class c = new Class();c.setName("08計(jì)本");Student s1 = new Student();s1.setName("張三");Student s2 = new Student();s2.setName("李四");c.getStudents().add(s1);c.getStudents().add(s2);//這里因?yàn)楸4鍯lass時(shí),class引用了臨時(shí)狀態(tài)的s1、s2;會(huì)保存失敗//必須在Class.hbm.xml中配置<set name="students" cascade="save-update"級(jí)聯(lián)保存更新才可以。 session.save(c); }/*** 通過班級(jí)端,查找學(xué)生*/@Testpublic void getStudentsByClass() {Class c = (Class) session.get(Class.class, Long.valueOf(2));Set<Student> students = c.getStudents();Iterator<Student> it = students.iterator();while(it.hasNext()){Student s = it.next();System.out.println(s);}//Student [id=1, name=李四]//Student [id=2, name=張三]}保存成功!查詢成功!
發(fā)出的sql:
?
?
第五節(jié):inverse 屬性 inverse屬性主要是在一對(duì)多、多對(duì)一雙向關(guān)系中,由一端來維護(hù)主外鍵關(guān)系; 測試代碼: @Testpublic void testAdd(){Class c=new Class();c.setName("09計(jì)本");Student s1=new Student();s1.setName("王五");session.save(c);session.save(s1);}@Testpublic void testInverse(){/*** Class和Student都是從session中獲取的,都已經(jīng)是持久化對(duì)象;* 對(duì)著兩個(gè)持久化對(duì)象進(jìn)行學(xué)生設(shè)置班級(jí)、班級(jí)也設(shè)置學(xué)生* 持久化對(duì)象設(shè)置關(guān)系,hibernate session檢測到之后就會(huì)進(jìn)行持久化操作(同步數(shù)據(jù)庫)*/Class c=(Class)session.get(Class.class, Long.valueOf(1));Student s=(Student)session.get(Student.class, Long.valueOf(1));s.setC(c);c.getStudents().add(s);/*** 可以看到學(xué)生設(shè)置班級(jí)、班級(jí)添加學(xué)生,兩端都維護(hù)了這個(gè)關(guān)系,都維護(hù)了這個(gè)外鍵。引入inverse屬性,只在某一端維護(hù)這個(gè)主外鍵關(guān)系。通常是在多的一端(one-to-many)設(shè)置inverse屬性。這里就是在學(xué)生Student端添加inverse=true屬性*/}1.先執(zhí)行testAdd,再執(zhí)行testInverse:
由于對(duì)student、class兩個(gè)持久化的對(duì)象進(jìn)行,互設(shè)關(guān)系的操作,hibernate session檢測到之后就會(huì)進(jìn)行持久化操作(同步數(shù)據(jù)庫):
確實(shí)數(shù)據(jù)庫發(fā)現(xiàn)已經(jīng)設(shè)置了外鍵關(guān)系,打印:
?
兩端都來維護(hù)這個(gè)關(guān)系,發(fā)出兩條sql語句,有點(diǎn)冗余,引入inverse:
Class.hbm.xml:
<hibernate-mapping package="com.cy.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="identity"></generator></id><property name="name" column="className"></property><set name="students" cascade="save-update" inverse="true"><!-- key外鍵,column是對(duì)應(yīng)Student表的外鍵classId 就是many-to-one中的column;--><key column="classId"></key><!-- class就是students屬性,對(duì)應(yīng)的集合中裝的類Student --><one-to-many class="com.cy.model.Student"/></set></class> </hibernate-mapping>2.再次先執(zhí)行testAdd,再執(zhí)行testInverse:
只有一條sql了,只在多的一方來維護(hù)這個(gè)外鍵關(guān)系;
?
?
?
第六節(jié):級(jí)聯(lián)刪除 刪除班級(jí)的時(shí)候,我們把學(xué)生也刪掉; /*** 級(jí)聯(lián)刪除* 刪除班級(jí)的時(shí)候,級(jí)聯(lián)刪除學(xué)生*/@Testpublic void testDeleteClassCascade(){Class c=(Class)session.get(Class.class, Long.valueOf(1));session.delete(c);} View Code 默認(rèn)是不能級(jí)聯(lián)刪除的,因?yàn)閯h除class的時(shí)候,classId被student表外鍵關(guān)聯(lián); 會(huì)報(bào)錯(cuò):?
設(shè)置cascade=delete就可以級(jí)聯(lián)刪除了; 修改Class.hbm.xml配置如下: <hibernate-mapping package="com.cy.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="identity"></generator></id><property name="name" column="className"></property><set name="students" cascade="delete" inverse="true"><key column="classId"></key><one-to-many class="com.cy.model.Student"/></set></class> </hibernate-mapping>console:
注:級(jí)聯(lián)刪除是一個(gè)危險(xiǎn)的操作,企業(yè)開發(fā)一般是不允許的;很可能導(dǎo)致其他業(yè)務(wù)數(shù)據(jù)的丟失。。。?
第七節(jié):一對(duì)多雙向自身關(guān)聯(lián)關(guān)系映射
?例如使用在菜單上,使用節(jié)點(diǎn)來模擬:
?com.cy.model.Node:
package com.cy.model;import java.util.HashSet; import java.util.Set;public class Node {private long id;private String name;private Node parentNode; //它的父節(jié)點(diǎn)private Set<Node> childNodes = new HashSet<Node>(); //它的子節(jié)點(diǎn)public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Node getParentNode() {return parentNode;}public void setParentNode(Node parentNode) {this.parentNode = parentNode;}public Set<Node> getChildNodes() {return childNodes;}public void setChildNodes(Set<Node> childNodes) {this.childNodes = childNodes;}} View CodeNode.hbm.xml:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.cy.model"><class name="Node" table="t_node"><id name="id" column="nodeId"><generator class="native"></generator></id><property name="name" column="nodeName"></property><many-to-one name="parentNode" column="parentId" class="com.cy.model.Node" cascade="save-update"></many-to-one><set name="childNodes" inverse="true"><key column="parentId"></key><one-to-many class="com.cy.model.Node"/></set></class> </hibernate-mapping>將Node.hbm.xml加入hibernate.cfg.xml中mapping配置;
測試代碼:
package com.cy.service;import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.After; import org.junit.Before; import org.junit.Test;import com.cy.model.Node; import com.cy.util.HibernateUtil;public class NodeTest {private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();private Session session;@Beforepublic void setUp() throws Exception {session = sessionFactory.openSession(); session.beginTransaction(); }@Afterpublic void tearDown() throws Exception {session.getTransaction().commit(); session.close(); }@Testpublic void testSaveMenu() {Node node=new Node();node.setName("根節(jié)點(diǎn)");Node subNode1=new Node();subNode1.setName("子節(jié)點(diǎn)1");Node subNode2=new Node();subNode2.setName("子節(jié)點(diǎn)2");subNode1.setParentNode(node);subNode2.setParentNode(node);session.save(subNode1);session.save(subNode2);} } View Code結(jié)果:
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/tenWood/p/7242710.html
總結(jié)
以上是生活随笔為你收集整理的Hibernate学习4—关联关系一对多映射2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: request对象中的get、post方
- 下一篇: Android Studio快捷键——编