3、對(duì)象關(guān)系映射_第1頁(yè)
3、對(duì)象關(guān)系映射_第2頁(yè)
3、對(duì)象關(guān)系映射_第3頁(yè)
3、對(duì)象關(guān)系映射_第4頁(yè)
3、對(duì)象關(guān)系映射_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、一、關(guān)系映射(重點(diǎn))這里的關(guān)系是指:對(duì)象之間的關(guān)系,并不是指數(shù)據(jù)庫(kù)的關(guān)系。存在以下關(guān)系:1、多對(duì)一單向雙向2、一對(duì)多單向雙向3、一對(duì)一單向(主鍵、外鍵)雙向(主鍵、外鍵)4、多對(duì)多單向雙向1. many2one (單 向)場(chǎng)景:用戶和組;從用戶角度來(lái),多個(gè)用戶屬于一個(gè)組(多對(duì)一),用戶3組(單向)使用hibernate開發(fā)的思路:先建立對(duì)象模型(領(lǐng)域模型),把實(shí)體抽取出來(lái)。目前兩個(gè)實(shí)體:用戶和組兩個(gè)實(shí)體,多個(gè)用戶屬于一個(gè)組,那么一個(gè)用戶都會(huì)對(duì)應(yīng)于一個(gè)組,所以用戶實(shí)體中應(yīng) 該有一個(gè)持有組的引用。(一)對(duì)象模型圖:(二)關(guān)系模型:t userid I name I groupid張三 201008

2、李四201008t_groupid |name*1201008(三)關(guān)聯(lián)映射的本質(zhì):將關(guān)聯(lián)關(guān)系映射到數(shù)據(jù)庫(kù),所謂的關(guān)聯(lián)關(guān)系是對(duì)象模型在內(nèi)存中一個(gè)或多個(gè)引用。實(shí)體類User實(shí)體類:public class User private int id; private String name; private Group group;public Group getGroup() return group; public void setGroup(Group group) this.group = group;public int getId() return id; public void set

3、Id(int id) this.id = id;public String getName() return name;public void setName(String name) = name;Group實(shí)體類:public class Group 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 na

4、me) = name; 實(shí)體類建立完后,開始創(chuàng)建映射文件,先建立簡(jiǎn)單的映射文件:xml方式:映射文件:、Group實(shí)體類的映射文件: generator class=native/ 2User實(shí)體類的映射文件: !-關(guān)聯(lián)映射 多對(duì)一的關(guān)系name:是維護(hù)的屬性(User.group),這樣表示在多的一端表里加入一個(gè)字段名稱為 group,但group與SQL中的關(guān)鍵字重復(fù),所以需要重新命名字段(column=groupid)這樣這個(gè)字 段(groupid)會(huì)作為外鍵參照數(shù)據(jù)庫(kù)中g(shù)roup表(t_group也叫一的一端),也就是就在多的一 端加入一個(gè)外鍵指向一的一端。-3、淤 標(biāo)簽:例如:關(guān)聯(lián)映

5、射多對(duì)一的關(guān)系name:是維護(hù)的屬性(User.group),這樣表示在多的一端表里加入一個(gè)字段名稱為group,但group與 SQL中的關(guān)鍵字重復(fù),所以需要重新命名字段(column=groupid).這樣這個(gè)字段(groupid)會(huì)作為外鍵參 照數(shù)據(jù)庫(kù)中g(shù)roup表 (t_group也叫一的一端),也就是就在多的一端加入一個(gè)外鍵指向一的一端。多對(duì)一存儲(chǔ)(先存儲(chǔ)group,對(duì)象持久化狀態(tài)后再保存user),即先存儲(chǔ)一的一方,再存儲(chǔ)多的一方session = sessionFactory.openSession();tx = session.beginTransaction();Group

6、group = new Group();group.setName(201008);session.save(group); /存儲(chǔ) Group 對(duì)象。User user1 = new User();user1.setName(張三);user1.setGroup(group);/設(shè)置用戶所屬的組User user2 = new User();user2.setName(李四);user2.setGroup(group);/設(shè)置用戶所屬的組/開始存儲(chǔ)session.save(user1);/ 存儲(chǔ)用戶session.save(user2);mit();/提交事務(wù)執(zhí)行后hibernate執(zhí)行以下

7、SQL語(yǔ)句:Hibernate: insert into t_group (name) values (?)Hibernate: insert into t_user (name, groupid) values (?, ?)Hibernate: insert into t user (name, groupid) values (?, ?)注意:如果上面的session.save(group)不執(zhí)行,則存儲(chǔ)不存儲(chǔ)不成功。則拋出 TransientObjectException 異 常。因?yàn)镚roup為Transient狀,Object的id沒(méi)有分配值。結(jié)果:persistent狀態(tài)的對(duì)象是不

8、能引用Transient狀態(tài)的對(duì)象以上代碼操作,必須首先保存group對(duì)象,再保存user對(duì)象。我們可以利用cascade(級(jí)聯(lián))方式,不需 要先保存group對(duì)象。而是直接保存user對(duì)象,這樣就可以在存儲(chǔ)user之前先把group存儲(chǔ)了。利用cascade屬性是解決TransientObjectException異常的一種手段。(七)重要屬性-cascade (級(jí)聯(lián)):級(jí)聯(lián)的意思是指定兩個(gè)對(duì)象之間的操作聯(lián)運(yùn)關(guān)系,對(duì)一個(gè)對(duì)象執(zhí)行了操作之后,對(duì)其指定的級(jí)聯(lián)對(duì)象也需 要執(zhí)行相同的操作,取值:all、none、save_update、delete1、all:代碼在所有的情況下都執(zhí)行級(jí)聯(lián)操作2、no

9、ne:在所有情況下都不執(zhí)行級(jí)聯(lián)操作(默認(rèn))3、save-update:在保存和更新的時(shí)候執(zhí)行級(jí)聯(lián)操作4、delete:在刪除的時(shí)候執(zhí)行級(jí)聯(lián)操作。1、xml例如:many-to-one name=group column=groupid cascade= saveupdate /多對(duì)一加載數(shù)據(jù)代碼如下:session =sessionFactory.openSession();tx = session.beginTransaction();User user = (User)session.load(User.class, 3);System.out.println(= + user.getNa

10、me();System.out.println(= + user.getGroup().getName();/提交事務(wù)mit();執(zhí)行后向SQL發(fā)出以下語(yǔ)句:Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.groupid as groupid0_0_ from t_user user0_ where user0_.id=?Hibernate: select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where

11、 group0_.id=?可以加載Group信息:因?yàn)椴捎昧薽any-to-one這個(gè)標(biāo)簽,這個(gè)標(biāo)簽會(huì)在多的一端(User)加一個(gè)外鍵,指 向一的一端(Group),也就是它維護(hù)了從多到一的這種關(guān)系,多指向一的關(guān)系。當(dāng)你加載多一端的數(shù)據(jù)時(shí),它就 能把一的這一端數(shù)據(jù)加載上來(lái)。當(dāng)加載User對(duì)象后hibernate會(huì)根據(jù)User對(duì)象中的groupid再來(lái)加載 Group信息給User對(duì)象中的group屬性。one2many 單向)在對(duì)象模型中,一對(duì)多的關(guān)聯(lián)關(guān)系,使用集合來(lái)表示。實(shí)例場(chǎng)景:班級(jí)對(duì)學(xué)生;Classes(班級(jí))和Student(學(xué)生)之間是(一對(duì)多),班級(jí)學(xué)生(單向)(一)對(duì)象模型:(二

12、)關(guān)系模型:t_classest_studentid 1 nameclassesidid 1 name001accp 7二T張三001T李四001一對(duì)多關(guān)聯(lián)映射利用了多對(duì)一關(guān)聯(lián)映射原理。 多對(duì)一關(guān)聯(lián)映射:在多的一端加入一個(gè)外鍵指向一的一端,一對(duì)多關(guān)聯(lián)映射:也是在多的一端加入一個(gè)外鍵指向 一的一端,兩者使用的策略是一樣的,只是各自所站的角度不同。實(shí)體類Classes實(shí)體類: public class Classes private int id; private String name; /一對(duì)多通常使用Set來(lái)映射,Set是不可重復(fù)內(nèi)容。 private Set students = new

13、HashSet(); public int getId() return id; public void setId(int id) this.id = id; public String getName() return name; public void setName(String name) = name;JStudent實(shí)體類: public class Student private int id; private String name; public int getId() return id; public void setId(int id) this.id = id; p

14、ublic String getName() return name; public void setName(String name) = name;Jxml方式:映射1、Student映射文件: generator class= native/ 2、Classes映射文件: generator class= native/! -標(biāo)簽 映射一對(duì)多(映射set集合),name=”屬性集合名稱,然后在用key標(biāo) 簽,在多的一端加入一個(gè)外鍵(column屬性指定列名稱)指向一的一端,再采用標(biāo)簽 說(shuō)明一對(duì)多,還指定標(biāo)簽中name=students這個(gè)集合中的類型要使用完整的類路徑(例如: class

15、=com.accp.hibernate.Student) -導(dǎo)出至數(shù)據(jù)庫(kù)(hbm ddl)生成的SQL語(yǔ)句: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 FK4B9

16、0757070CFE27A (classesid), add constraint FK4B90757070CFE27A foreign key (classesid) references t_classes (id)一對(duì)多單向存儲(chǔ)實(shí)例,即先保存多的 方,再保存 的 方:session = sessionFactory.openSession();tx = session.beginTransaction();Student studentl = new Student();student1.setName( 10);session.save(studentl); /必需先存儲(chǔ),否則在保存c

17、lassess時(shí)出錯(cuò).Student student2 = new Student();student2.setName(張三);session.save(student2); /必需先存儲(chǔ),否則在保存classess時(shí)出錯(cuò).Set students = new HashSet();students.add(studentl);students.add(student2);Classes classes = new Classes();classes.setName( accp);classes.setStudents(students);session.save(classes);mit()

18、;(七)生成的SQL語(yǔ)句:Hibernate:insertintot_student(name)values(?)Hibernate:insertintot_student(name)values(?)Hibernate:insertintotclasses(name)values(?)Hibernate: update t_student set classesid=? where id=?Hibernate: update t_student set classesid=? where id=?一對(duì)多,在一的一端維護(hù)關(guān)系的缺點(diǎn):因?yàn)槭窃谝坏囊欢司S護(hù)關(guān)系,這樣會(huì)發(fā)出多余的更新語(yǔ)句,這樣在批量

19、數(shù)據(jù)時(shí),效率不高。還有一個(gè),當(dāng)在多的一端的那個(gè)外鍵設(shè)置為非空時(shí),則在添加多的一端數(shù)據(jù)時(shí)會(huì)發(fā)生錯(cuò)誤,數(shù)據(jù)存儲(chǔ)不成功。一對(duì)多單向數(shù)據(jù)加載:session = sessionFactory.openSession();tx = session.beginTransaction();Classes classes = (Classes)session.load(Classes.class, 2);System.out.println(= + classes.getName();Set students = classes.getStudents();for (Iterator iter = stude

20、nts.iterator();iter.hasNext();)Student student = iter.next();System.out.println(student.getName();mit();(十)加載生成SQL語(yǔ)句:Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?Hibernate: select students0_.classesid as classesid1_, students0_.id

21、as id1_, students0_.id as id1_0_, students0_.name as name1_0_ from t_student students0_ where students0_.classesid=?one2many (雙向)是加載學(xué)生時(shí),能夠把班級(jí)加載上來(lái)。當(dāng)然加載班級(jí)也可以把學(xué)生加載上來(lái)(學(xué)生 班級(jí))xml方式:映射學(xué)生映射文件修改后的:generator class= native/如果在一對(duì)多的映射關(guān)系中采用一的一端來(lái)維護(hù)關(guān)系的話會(huì)存在以下兩個(gè)缺點(diǎn):如果多的一端那個(gè)外鍵設(shè)置為 非空時(shí),則多的一端就存不進(jìn)數(shù)據(jù);會(huì)發(fā)出多于的Update語(yǔ)句,這樣會(huì)影響效率。

22、所以常用對(duì)于一對(duì)多的映 射關(guān)系我們?cè)诙嗟囊欢司S護(hù)關(guān)系,并讓一的一端維護(hù)關(guān)系失效(見下面屬性)。代碼:!-fe簽映射一對(duì)多(映射set集合),name=屬性集合名稱然后在用fe簽,在多的一端加入一個(gè)外鍵(column屬性指定列名稱)指向一的一端再采用標(biāo)簽說(shuō)明一對(duì)多,還指定標(biāo)簽中name=students這個(gè)集合中的類型要使用完整的類路徑(例如:class=com.accp.hibernate.Student)inverse=true:從一的一端維護(hù)關(guān)系失效(反轉(zhuǎn)),(默認(rèn)false)這樣如果在一的一端維護(hù)關(guān)系則不會(huì)發(fā)出U pdate語(yǔ)句。-數(shù)據(jù)保存:一對(duì)多數(shù)據(jù)保存,從多的一端進(jìn)行保存:sessi

23、on = sessionFactory.getSession();tx = session.beginTransaction();Classes classes = new Classes();classes.setName(accp);session.save(classes);Student student1 = new Student();student1.setName(張三);student1.setClasses(classes);session.save(student1);Student student2 = new Student();student2.setName(李四)

24、;student2.setClasses(classes);session.save(student2);/提交事務(wù)mit();關(guān)于 inverse屬性:inverse主要用在一對(duì)多和多對(duì)多雙向關(guān)聯(lián)上,inverse可以被設(shè)置到集合標(biāo)簽上,默認(rèn)inverse 為false,所以我們可以從一的一端和多的一端維護(hù)關(guān)聯(lián)關(guān)系,如果設(shè)置inverse為true,則我們只能從多的一端維護(hù)關(guān)聯(lián)關(guān)系。注意:雙向關(guān)聯(lián)中雙方都設(shè)置inverse= fals e的話,必會(huì)導(dǎo)致雙方都重復(fù)更新同一個(gè)關(guān)系。但是如果雙方都設(shè) 立inverse= true的話,雙方都不維護(hù)關(guān)系的更新,這也是不行的,好在一對(duì)多中的一端:man

25、y-to-one默認(rèn) 是inverse= false,避免了這種錯(cuò)誤的產(chǎn)生。(四)Inverse 和 cascade 區(qū)別:Inverse是關(guān)聯(lián)關(guān)系的控制方向Casecade操作上的連鎖反應(yīng)(五)一對(duì)多雙向關(guān)聯(lián)映射總結(jié):在一的一端的集合上使用key,在對(duì)方表中加入一個(gè)外鍵指向一的一端在多的一端采用 many-to-one注意:keyfe簽指定的外鍵字段必須和many-to-one指定的外鍵字段一致,否則引用字段的錯(cuò)誤如果在一的一端維護(hù)一對(duì)多的關(guān)系,hibernate會(huì)發(fā)出多余的update語(yǔ)句,所以我們一般在多的一端來(lái)維護(hù)關(guān) 系。4. one2one關(guān)聯(lián)映射兩個(gè)對(duì)象之間是一對(duì)一的關(guān)系,如Per

26、son-IdCard(人身份證號(hào))有兩種策略可以實(shí)現(xiàn)一對(duì)一的關(guān)聯(lián)映射 主鍵關(guān)聯(lián):即讓兩個(gè)對(duì)象具有相同的主鍵值,以表明它們之間的一一對(duì)應(yīng)的關(guān)系;數(shù)據(jù)庫(kù)表不會(huì)有額外 的字段來(lái)維護(hù)它們之間的關(guān)系,僅通過(guò)表的主鍵來(lái)關(guān)聯(lián)。 唯一外鍵關(guān)聯(lián)(重要):外鍵關(guān)聯(lián),本來(lái)是用于多對(duì)一的配置,但是如果加上唯一的限制之后,也可以用 來(lái)表示一對(duì)一關(guān)聯(lián)關(guān)系。IdCardid intcardNo varchar(18)對(duì)象模型Persionid in!name varchar(20)(一)唯一外鍵關(guān)聯(lián)-單向1、說(shuō)明:人一- 身份證號(hào)(PersonIdCard),從IdCard看不至I Person對(duì)象2、對(duì)象模型需要在Per

27、son類中持有IdCard的一個(gè)引用idCard,【J IdCard中沒(méi)有Person的引用Personf-一IdCard金id : int &name : String 鈕dCad : IdCard翎d : int ,cadNo : String1 ;3、關(guān)系模型關(guān)系模型目的:是實(shí)體類映射到關(guān)系模型(數(shù)據(jù)庫(kù)中),是要求persion中添加一個(gè)外鍵指向idcardt personidInamelidcard (唯一)I 張三 I 001I李四| 002t idcardid|cardNo卜 001 002|3625311986080302584、實(shí)體類:/

28、*人一實(shí)體類*/public class Person private int id;private String name;private IdCard idCard; /弓I用IdCard對(duì)象public int getId() return id; public void setId(int id) this.id = id;public String getName() return name;public void setName(String name) = name;public IdCard getIdCard() return idCard;public void setId

29、Card(IdCard idCard) this.idCard = idCard; 5、xml映射IdCard實(shí)體類的映射文件:因?yàn)镮dCard是被引用的,所以沒(méi)有什么特殊的映射generator class=native/Person實(shí)體類的映射文件在映射時(shí)需要添加一個(gè)外鍵的映射,就是指定IdCard的引用的映射。這樣映射到數(shù)據(jù)庫(kù)時(shí),就會(huì)自動(dòng)添加 一個(gè)字段并作用外鍵指向被引用的表!- :在多的一端(當(dāng)前Person端),加入一個(gè)外鍵(當(dāng)前為idCard)指向一的 一端(當(dāng)前IdCard),但多對(duì)一關(guān)聯(lián)映射字段是可以重復(fù)的,所以需要加入一個(gè)唯一條件unique=true,這樣就可以此字段唯一了

30、。-6、存儲(chǔ)測(cè)試Session session = sf.getCurrentSession();IdCard idCard = new IdCard();idCard.setCardNo(3625311985080302 65);session.beginTransaction();/如果先不保存idCard,則出拋出Transient異常,因?yàn)閕dCard不是持久化狀態(tài)。session.save(idCard);Person person = new Person();person.setName(張三);person.setIdCard(idCard);session.save(pers

31、on);session.getTransaction().commit();(二)唯一外鍵關(guān)聯(lián)-雙向1、說(shuō)明:人 身份證號(hào)(PersonIdCard)雙向:互相持有對(duì)方的引用2、對(duì)象模型:Person7 zIdCard%id : int &name : String idCard : IdCard曼id : int cardNo : String person : Person3、關(guān)系模型:關(guān)系模型沒(méi)有任務(wù)變化,同單向4、實(shí)體類:實(shí)體類,只是相互持有對(duì)象的引用,并且要求getter和setter方法5、xml映射Person實(shí)體類映射文件:同單向的沒(méi)有變化IdCard實(shí)體類映射文件:如果使用同

32、樣的方法映射,這樣就會(huì)在表中也添加一個(gè)外鍵指向?qū)ο?,但?duì)象已 經(jīng)有一個(gè)外鍵指向自己了,這樣就造成了庸字段,因?yàn)椴恍枰诒砹硗馓砑幼侄?,而是讓hibernate在加載 這個(gè)對(duì)象時(shí),會(huì)根據(jù)對(duì)象的ID到對(duì)方的表中查詢外鍵等于這個(gè)ID的記錄,這樣就把對(duì)象加載上來(lái)了。也同 樣需要使用one-to-one標(biāo)簽來(lái)映射,但是需要使用property-ref屬性來(lái)指定對(duì)象持有你自己的引用的成員屬 性名稱(是gettxxxx后面的名稱),這樣在生成數(shù)據(jù)庫(kù)表時(shí),就不會(huì)再添加一個(gè)多于的字段了。數(shù)據(jù)加載時(shí) hibernate會(huì)根據(jù)這些配置自己加載數(shù)據(jù)!-fe簽:告訴hibernate如何加載其關(guān)聯(lián)對(duì)象 property

33、-refM性:是根據(jù)哪個(gè)字段進(jìn)行比較加載數(shù)據(jù)- (三)主鍵關(guān)聯(lián)-單向(不重要)主鍵關(guān)聯(lián):即讓兩個(gè)對(duì)象具有相同的主鍵值,以表明它們之間的一一對(duì)應(yīng)的關(guān)系;數(shù)據(jù)庫(kù)表不會(huì)有額外的字 段來(lái)維護(hù)它們之間的關(guān)系,僅通過(guò)表的主鍵來(lái)關(guān)聯(lián)。1、說(shuō)明:人。 身份證號(hào)(Person IdCard),從IdCard看不至I Person對(duì)象2、對(duì)象模型站在人的角度來(lái)看,對(duì)象模型與唯一外鍵關(guān)聯(lián)一個(gè),只是關(guān)系模型不同3、關(guān)系模型因?yàn)槭莗erson引用idcard,所以idcard要求先有值。而person的主鍵值不是自己生成的。而是參考idcard4、實(shí)體類:實(shí)體類同一對(duì)一唯一外鍵關(guān)聯(lián)的實(shí)體類一個(gè),在person對(duì)象中持有

34、idcard對(duì)象的引用(代碼見唯一外鍵關(guān)系)5、xml映射IdCard映射文件,先生成IDgenerator class= native/Person實(shí)體類映射文件,ID是根據(jù)IdCard主鍵值!-因?yàn)橹麈I不是自己生成的,而是作為一個(gè)外鍵(來(lái)源于其它值),所以使用foreign生成策略 foreign :使用另外一個(gè)相關(guān)聯(lián)的對(duì)象的標(biāo)識(shí)符,通常和聯(lián)合起來(lái)使用。再使用元素 的屬性值指定相關(guān)聯(lián)對(duì)象(這里Person相關(guān)聯(lián)的對(duì)象為idCard,則標(biāo)識(shí)符為idCard的id) 為了能夠在加載person數(shù)據(jù)同時(shí)加載IdCard數(shù)據(jù),所以需要使用一個(gè)標(biāo)簽來(lái)設(shè)置這 個(gè)功能。-!- 元素屬性name的值是固定

35、為property - idCard!- 標(biāo)簽表示如何加載它的引用對(duì)象(這里引用對(duì)象就指idCard這里的name值是idCard),同時(shí)也 說(shuō)是一對(duì)一的關(guān)系。默認(rèn)方式是根據(jù)主鍵加載(把person中的主鍵取出再到IdCard中來(lái)取相關(guān) IdCard數(shù)據(jù)。)我們也說(shuō)過(guò)此主鍵也作為一個(gè)外鍵引用7IdCard,所以需要加一個(gè)數(shù)據(jù)庫(kù)限制(外 鍵約束)constrained=true-6、存,測(cè)試session = HibernateUtils.getSession();tx = session.beginTransaction();IdCard idCard = new IdCard();idCar

36、d.setCardNo;Person person = new Person();person.setName(張三);person.setIdCard(idCard);/不會(huì)出現(xiàn) TransientObjectException 異常/因?yàn)橐粚?duì)一主鍵關(guān)鍵映射中,默認(rèn)了 cascade屬性。session.save(person);mit();7、總結(jié)讓兩個(gè)實(shí)體對(duì)象的ID保持相同,這樣可以避免多余的字段被創(chuàng)建idCard(四)主鍵關(guān)聯(lián)-雙向(不重要)主鍵關(guān)聯(lián):即讓兩個(gè)對(duì)象具有相同的主鍵值,以表明它們之間的一一對(duì)應(yīng)的關(guān)系;數(shù)據(jù)庫(kù)表不會(huì)有額外的字 段來(lái)維護(hù)它

37、們之間的關(guān)系,僅通過(guò)表的主鍵來(lái)關(guān)聯(lián)。主鍵關(guān)聯(lián)映射,實(shí)際是數(shù)據(jù)庫(kù)的存儲(chǔ)結(jié)構(gòu)并沒(méi)有變化,只是要求雙方都可以持有對(duì)象引用,也就是說(shuō)實(shí)體模型變化,實(shí)體類都相互持有對(duì)方引用。另外映射文件也變化了。1、xml映射Person實(shí)體類映射文件不變,IdCard 如下:5.多對(duì)多關(guān)聯(lián)映射 單向(many-to-many)一般的設(shè)計(jì)中,多對(duì)多關(guān)聯(lián)映射,需要一個(gè)中間表 Hibernate會(huì)自動(dòng)生成中間表Hibernate使用many-to-many標(biāo)簽來(lái)表示多對(duì)多的關(guān)聯(lián)多對(duì)多的關(guān)聯(lián)映射,在實(shí)體類中,跟一對(duì)多一樣,也是用集合來(lái)表示的。實(shí)例場(chǎng)景:用戶與他的角色(一個(gè)用戶擁有多個(gè)角色,一個(gè)角色還可以屬于多個(gè)用戶)對(duì)象模型

38、:關(guān)系模型:t_usert_user_role(第三方表,表示 user 和 role 關(guān)系)t_roleid 1 nameid 1 nameid I name1張三1李四1王五1111129IoI區(qū)域經(jīng)理I業(yè)務(wù)主管I項(xiàng)目經(jīng)理2|2I3I13I23I3Role實(shí)體類:public class Role private int id;private String name;public int getId() return id;public void setId(int id) this.id = id;public String getName() ;public void setName(

39、String name) ,=name,User實(shí)體類:public class User private int id;private String name;private Set roles; /Role對(duì)象的集合 public int getId() return id;public void setId(int id) this.id = id;public String getName() Role映射文件:generator class= native/User映射文件:!-使用標(biāo)簽映射集合(set),標(biāo)簽中的name值為對(duì)象屬性名(集合roles),而使用table 屬性是用于

40、生成第三方表名稱,例:table=t_user_role,但是第三方面中的字段是自動(dòng)加入的,作為外鍵 分別指向其它表。所以表標(biāo)簽設(shè)置,例:,意思是:在第三方表(t_user_role)中加入一個(gè) 外鍵并且指向當(dāng)前的映射實(shí)體類所對(duì)應(yīng)的表(t_user).使用來(lái)指定此映射集合所對(duì)象的類 (實(shí)例類),并且使用column屬性加入一個(gè)外鍵指向Role實(shí)體類所對(duì)應(yīng)的表(t_role)-導(dǎo)出至數(shù)據(jù)庫(kù)表所生成SQL語(yǔ)句create table t_role (id integer not null auto_increment, name varchar(255), primary key (id)crea

41、te table t_user (id integer not null auto_increment, name varchar(255), primary key (id)create table t_user_role (userid integer not null, roleid integer not null, primary key (userid, roleid)alter table t_user_role add index FK331DEE5F1FB4B2D4 (roleid), add constraintFK331DEE5F1FB4B2D4 foreign key

42、(roleid) references t_role (id)alter table t_user_role add index FK331DEE5F250A083E (userid), add constraintFK331DEE5F250A083E foreign key (userid) references t_user (id)注:根據(jù)DDL語(yǔ)句可以看出第三方表的主鍵是一個(gè)復(fù)合主鍵(primary key (userid, roleid),也就是說(shuō) 記錄不可以有相同的數(shù)據(jù)。多對(duì)多關(guān)聯(lián)映射單向數(shù)據(jù)存儲(chǔ):session = HibernateUtils.getSession ();tx

43、= session.beginTransaction();Role r1 = new Role();r1.setName(區(qū)域經(jīng)理);session.save(r1);Role r2 = new Role();r2.setName(業(yè)務(wù)主管);session.save(r2);Role r3 = new Role();r3.setName(項(xiàng)目經(jīng)理);session.save(r3);User u1 = new User();u1.setName(張三);Set u1Roles = new HashSet();u1Roles.add(r1);u1Roles.add(r2);u1.setRole

44、s(u1Roles);User u2 = new User();u2.setName(李四);Set u2Roles = new HashSet();u2Roles.add(r2);u2Roles.add(r3);u2.setRoles(u2Roles);User u3 = new User();u3.setName(王五);Set u3Roles = new HashSet();u3Roles.add(r1);u3Roles.add(r2);u3Roles.add(r3);u3.setRoles(u3Roles);session.save(u1);session.save(u2);sessi

45、on.save(u3);mit();發(fā)出SQL語(yǔ)句:Hibernate:insertintot_role(name) values(?)Hibernate:insertintot_role(name) values(?)Hibernate:insertintot_role(name) values(?)Hibernate:insertintot_user(name) values(?)Hibernate:insertintot_user(name) values(?)Hibernate:insertintot_user(name) values(?)Hibernate:insertintot_

46、user_role (userid,roleid) values (?, ?)Hibernate:insertintot_user_role (userid,roleid) values (?, ?)Hibernate:insertintot_user_role (userid,roleid) values (?, ?)Hibernate:insertintot_user_role (userid,roleid) values (?, ?)Hibernate:insertintot_user_role (userid,roleid) values (?, ?)Hibernate:insertintot_user_role (userid,roleid) values (?, ?)Hibernate:insertintotuserrole (userid,roleid) values (?, ?)注:前三條SQL語(yǔ)句,添加Role記錄,第三條到第六條添加User,最后7條SQL語(yǔ)句是在向第三方表 (t_user_role)中添加多對(duì)多關(guān)系(User與Role關(guān)系)多對(duì)多關(guān)聯(lián)映射單向數(shù)據(jù)加載:se

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論