對於hibernate中,集合屬性在Hibernate的對應檔中是非常常見的,也是非常重要的內容,理解和熟練掌握常用的集合屬性則顯得更為重要。在hibernate的設定檔中,例如每個人的考試成績,就是典型的Map結構,每門功課對應一門成績。或者更簡單的集合屬性,某個企業的部門,一個企業通常對應多個部門等。集合屬性是現實生活中非常普遍的屬性關聯性。集合屬性大致有兩種:第一種是單純的集合屬性,例如像List,Set或數組等集合屬性;還有一種就是Map結構的集合屬性。每個屬性都有對應的key映射.
集合屬性的元素大致有如下幾種:
(1)<set>元素:可以映射類型為java.util.Set介面的屬性,它的元素存放沒有順序且不允許重複,也可以映射類型為java.util.SortSet介面的屬性,它的元素可以按自然屬性排序
(2)<list>元素:可以映射類型為java.util.List介面的屬性,它需要在結合屬性對象的資料庫表中用一個額外的索引列儲存每一個元素的位置,即是有屬性可重複的。
(3)<bag>元素:可以映射java.util.Collection介面的屬性,它的元素可能重複,但不儲存屬性,和set差不多,正因為有它,是因為如果通常使用list比較多,並且不想讓添加一列的話,就用它。
(4)<map>元素:可以映射為java.util.Map介面的屬性,它的元素以索引值對的形式儲存,也是無序的,也可以映射類型為java.util.SortMap介面的屬性,它的元素可以按自然順序排序。
(5)<array>元素:可以映射類型為數組的屬性,但在實際運用中用的極少
在這篇部落格我們主要來看一下,map屬性對應的詳細情況
Map屬性也是比較常見的屬性類型,比如,一個組隊內有多個學生,學生就是一個名字對應著相應的名字,下面我們就根據這個樣本詳細看一下:
首先看一下實體:team.java
public class Team{ private Stringid; private StringteamName; private Mapstudents = new HashMap();*************set、get方法}
下面我們來具體看一下具體的實體映射配置
Team.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> <classname="com.shengsiyuan.hibernate.Team" table="team"> <idname="id" column="id" type="string"> <generatorclass="uuid"></generator> </id> <propertyname="teamName" column="teamName"type="string"></property> <mapname="students" table="student"> <keycolumn="team_id"></key> <indexcolumn="name" type="java.lang.String"></index><!--指定的是Map中的key值 --> <element column="description" type="java.lang.String"></element><!--指定的是Map中的value值 --> </map> </class></hibernate-mapping>
從上邊設定檔可以看出,其實map屬性對應的設定檔其他的配置都和我們以前配置一樣,只是在配置map屬性的時候有點不一樣而已,下面我們就具體看一下map屬性配置:首先要給大家說明的是,雖然我們只有一個設定檔,但是上面的配置會產生兩個資料庫表的,map屬性裡的會單獨產生一個資料庫表,這個表包含map的key和value,還有一個外鍵。map屬性配置內的key標籤指定的是map對應表中資料所參考的team的id,也就是說這個外鍵對應team的主鍵。Map標籤內的index標籤對應指的是map資料中的key值,element標籤指定的是map資料中的value值。
其實上面我們看到的map中value值只是單一資料型別,但是在實際開發中,這裡的value大多數都是對象的形式的。現在我們還是以上面的例子來看一下,這裡的value是對象的時候我們該如何配置:當value是對象的時候,我們就不能再簡單的用一個設定檔來產生兩個資料庫表了,這時我們需要建立我們的team類。還需要建立value對應的student實體類
首先我們來看一下實體:Team.java
public class Team{ private String id; private StringteamName; private Mapstudents = new HashMap();*********省略set、get方法}
Student.java
public class Student{ private String id; private StringcardId; private Stringname; private int age; private Team team;********省略set、get方法}
下面我們繼續來看一下相關的實體對應檔
Team.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> <classname="com.shengsiyuan.hibernate.Team" table="team"> <idname="id" column="id" type="string"> <generatorclass="uuid"></generator> </id> <propertyname="teamName" column="teamName"type="string"></property> <mapname="students" table="student" cascade="all"> <keycolumn="team_id"></key> <index column="card_id"type="java.lang.String"></index> <!--指定的是Map中的key值 --> <one-to-manyclass="com.shengsiyuan.hibernate.Student"/> </map> </class></hibernate-mapping>
通過上面的設定檔我們可以看出,這個設定檔幾乎和單一資料型別的設定檔差不多,僅僅不同的是map標籤內的element標籤換成了one-to-many標籤,這樣充分可以說明:
map標籤中的element子標籤映射的是原子類型(string,date,int,long…),即能夠直接映射到資料庫表欄位上的類型,而one-to-many映射的則是實體類型,指的是無法映射到表的某個欄位,而是要映射到整張表的類型。但有一點需要注意的是,在map標籤中的one-to-many中不要設定inverse=true,因為如果要讓map值中的對象去維護兩者之間的關係的話,在儲存資料中很有可能外鍵添加不上,被設定為null
下面在來看一下student.hbm.xml
<?xmlversion="1.0"?><!DOCTYPEhibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <classname="com.shengsiyuan.hibernate.Student"table="student"> <id name="id" column="id"type="string"> <generatorclass="uuid"></generator> </id> <property name="cardId"column="card_id" type="string"></property> <property name="name"column="name" type="string"></property> <property name="age"column="age" type="int"></property> <many-to-one name="team"column="team_id" class="com.shengsiyuan.hibernate.Team"cascade="none" fetch="join"> </many-to-one> </class></hibernate-mapping>
細心的同學可以發現,這個設定檔和一對多關聯性映射中的多的一方配置的差不多,其實就是一樣的,所以在這裡就不在贅述了。