日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Hibernate】Hibernate实体映射——单边的一对多关系

發布時間:2024/4/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Hibernate】Hibernate实体映射——单边的一对多关系 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ?數據庫中的表是有關系的,兩個表之間可以通過外鍵關聯。如果把表抽象為實體類,這些關系可以抽象為實體之間的一對一,一對多,多對一等關系。hibernate能處理這些復雜的關系,前提是要正確配置這些關系。

單邊的一對多關系

???? 單邊的一對多關系是指一方有集合屬性,包含多個多方,而多方沒有一方的引用。比較典型的是用戶與電子郵件。其中,用戶為一方,電子郵件為多方,一個用戶可以擁有多個電子郵件記錄。

Person.java中有id、name、List<Email>;

Email.java中有id、email;

一個person有多個email,而email中沒有person;

對應的表中

tb_person:id、name;

tb_email:id、email、person_id;

若person中有email外鍵,則一個person的email外鍵要有多個id,不現實;而email中有person外鍵,一個email只需要有一個person的外鍵即可

總結:

一個person有多個email,則person類中有多個email,而person表中沒有email外鍵,email表中有person外鍵;

?

具體實現如下:

?

Person.java

package com.lmb.hibernate.bean;import java.util.ArrayList; import java.util.List;import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinColumns; import javax.persistence.OneToMany; import javax.persistence.OrderBy; import javax.persistence.Table;@Entity @Table(name="tb_person") public class Person {@Id@GeneratedValue(strategy=GenerationType.AUTO)private Integer id;private String name;//一對多配置,并配置列關系<span style="color:#ff0000;">@OneToMany(fetch=FetchType.EAGER,targetEntity=Email.class,cascade={CascadeType.PERSIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH})@JoinColumns(value = { @JoinColumn(name="person id",referencedColumnName="id") })//配置排序方法@OrderBy(value="email desc") </span> private List<Email> emails=new ArrayList<Email>();public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Email> getEmails() {return emails;}public void setEmails(List<Email> emails) {this.emails = emails;}}


????? Person實體中使用@OneToMany配置一對多關系。fetch配置加載方式(延遲加載fetch=FetchType.LAZY、即時加載fetch=FetchType.EAGER);targetEntity配置集合屬性中的類型,由于emails屬性類型為List<Email>,用反省制定了集合內為Email對象,因此targetEntity可省略;cascade配置級聯方式,本例配置為PERSIST、REMOVE、MERGE、REFRESH,表示在保存、刪除、修改、刷新Person類時會自動在數據庫中保存、刪除、修改、刷新屬于它的Email對象。配置級聯關系后,可以通過操作Person類來操作Email類。該配置也等同于CascadeType.ALL。@OrderBy配置排序方式,本例將Email按照email列降序排列。

??? Email實體類比較簡單,由于是單邊關系映射,Email中沒有用戶實體的引用,只是一個簡單的POJO。

?

Email.java

package com.lmb.hibernate.bean;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;@Entity @Table(name="tb_email") public class Email {@Id@GeneratedValue(strategy=GenerationType.AUTO)private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}


??? 配置完畢后要將Person類和Email類在hibernate配置文件中聲明為實體類。實體類要配置在<session-factory? />中。

?

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration><session-factory><property name="dialect">org.hibernate.dialect.MySQLDialect</property><property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property><property name="connection.username">lmb</property><property name="connection.password">lmb</property><property name="connection.driver_class">com.mysql.jdbc.Driver</property><span style="color:#ff0000;"><mapping class="com.lmb.hibernate.bean.Person" /><mapping class="com.lmb.hibernate.bean.Email" /> </span> </session-factory></hibernate-configuration>

?

以上使用@注解實現的,當然我們還可以使用XML配置的方式實現,這了我就不在列出。


延遲加載與即時加載

即時加載(Eagar Fetching),查詢Person的時候自動加載相關的Email

延遲加載(Lazy Fetching),只有在需要的時候才查詢Email(默認)

延遲加載異常

?? 一般來說,延時加載比即時加載節省資源。但是如果處理不當,延遲加載容易拋出延時加載異常(LazyInitializationException)。這是因為延遲加載時,只有第一次調用person.getEmail()才會加載emails數據,如果這時候數據庫連接已經關閉了,就會因為無法加載數據而拋出異常。

?

解決辦法:(兩種)?

1、在session關閉前調用一次上面的方法(person.getEmail()),強迫hibernate加載Email數據;session關閉后JDBC連接就關閉了,無法再從數據庫讀取任何數據了。

2、延遲session的范圍,使session關閉前完成所有的業務邏輯。

總結

以上是生活随笔為你收集整理的【Hibernate】Hibernate实体映射——单边的一对多关系的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。