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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

hibernate 集合类(Collections)映射

發布時間:2025/6/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hibernate 集合类(Collections)映射 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?Hibernate可以持久化以下java集合的實例, 包括java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, 和任何持久實體或值的數組(使用Set集合類型是最好的選擇)。類型為java.util.Collection或者java.util.List的屬性還可以使用"bag"語義來持久。用于持久化的集合,除了集合接口外,不能保留任何實現這些接口的類所附加的語義(例如:LinkedHashSet帶來的迭代順序)。所有的持久化集合,實際上都各自按照 HashMap, HashSet, TreeMap, TreeSet 和 ArrayList 的語義直接工作。更深入地說,對于一個包含集合的屬性來說,必須把Java類型定義為接口(也就是Map, Set 或者List等),而絕不能是HashMap, TreeSet 或者 ArrayList。存在這個限制的原因是,在你不知道的時候,Hibernate暗中把你的Map, Set 和 List 的實例替換成了它自己的關于Map, Set 或者 List 的實現。(所以在你的程序中,謹慎使用==操作符。)(說明: 為了提高性能等方面的原因,在Hibernate中實現了幾乎所有的Java集合的接口(為了實現懶加載的一些特性) 。)所有的有序集合類(maps, lists, arrays)都擁有一個由<key>和 <index>組成的主鍵。 這種情況下集合類的更新是非常高效的——主鍵已經被有效的索引,因此當Hibernate試圖更新或刪除一行時,可以迅速找到該行數據。集合(sets)的主鍵由<key>和其他元素字段構成。 對于有些元素類型來說,這很低效,特別是組合元素或者大文本、大二進制字段; 數據庫可能無法有效的對復雜的主鍵進行索引。 另一方面,對于一對多、多對多關聯,特別是合成的標識符來說,集合也可以達到同樣的高效性能。( 附注:如果你希望SchemaExport為你的<set>創建主鍵, 你必須把所有的字段都聲明為not-null="true"。)<idbag>映射定義了代理鍵,因此它總是可以很高效的被更新。事實上, <idbag>擁有著最好的性能表現。Bag是最差的。因為bag允許重復的元素值,也沒有索引字段,因此不可能定義主鍵。 Hibernate無法判斷出重復的行。當這種集合被更改時,Hibernate將會先完整地移除 (通過一個(in a single DELETE))整個集合,然后再重新創建整個集合。 因此Bag是非常低效的。

?一、Set集合映射

我的前幾篇文章,many-to-many, many-to-one中都用的是Set集合映射,在此不再累述。

?當實體類中有HashSet屬性時,它是如何進行初始化的呢?當持久化這個實體類的一個實例,比如調用persist()方法進行了持久化時,hibernate將自動利用hibernate自己實現了Set接口的類替換掉HashSet。所以一定要防止出現如下所示的錯誤:

Java代碼 ?
  • HashSet<Employee>?hSet?=?(HashSet<Employee>)depart.getEmps();?//Error??
  • ?當運行時,會出現如下的異常:

    java.lang.ClassCastException: org.hibernate.collection.PersistentSet cannot be cast to java.util.HashSet

    二、List集合映射

    1. 實體類:

    實體類還是采用Department和Employee,詳見我寫的多對一(many-to-one)文章,在它們的基礎上進行修改如下所示:

    將原Department實體類中的Set替換成List,如下所示:

    Java代碼 ?
  • package?com.reiyen.hibernate.domain;??
  • ??
  • public?class?Department?{??
  • ??
  • ????private?int?id;??
  • ????private?String?name;??
  • ????private?List<Employee>?emps;??
  • ???????//Setter和Getter方法??
  • }??
  • 在原Employee實體類中增加了重寫的toString()方法,方法如下:

    Java代碼 ?
  • @Override??
  • ????public?String?toString()?{??
  • ????????return?"id="?+?this.id?+?"?name="?+?this.name;??
  • ????}??
  • ?2. 配置文件:

    修改Department.hbm.xml配置文件,其它的還是保持以前的不變,修改的Department.hbm.xml配置文件如下:

    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?package="com.reiyen.hibernate.domain">??
  • ????<class?name="Department"?>??
  • ????????<id?name="id"?>??
  • ????????????<generator?class="native"?/>??
  • ????????</id>??
  • ????????<property?name="name"?/>??
  • ????????<!--????
  • ????????<set?name="emps">??
  • ????????<key?column="depart_id"?/>??
  • ????????<one-to-many?class="Employee"/>??
  • ????????</set>-->??
  • ????????<list?name="emps">??
  • ????????<key?column="depart_id"?/>??
  • ????????<!--?list-index:用來記錄加入list集合的元素的順序?,會一定程度影響性能,所以可以使用bag替代list-->??
  • ????????<list-index?column="order_col"?/>??
  • ????????<one-to-many?class="Employee"/>??
  • ????????</list>??
  • ????</class>??
  • </hibernate-mapping>??
  • ?3.測試類(只是對many-to-one中的測試類進行了少量的修改),如下所示:

    Java代碼 ?
  • public?class?Many2One?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????Department?depart?=?add();??
  • ????????Department?department?=?queryDepart(depart.getId());??
  • ????}??
  • ??
  • ????static?Department?queryDepart(int?departId)?{??
  • ????????Session?s?=?null;??
  • ????????Transaction?tx?=?null;??
  • ????????try?{??
  • ????????????s?=?HibernateUtil.getSession();??
  • ????????????tx?=?s.beginTransaction();??
  • ????????????Department?depart?=?(Department)?s.get(Department.class,?departId);??
  • ????????????System.out.println("emps:"?+?depart.getEmps());??
  • ????????????tx.commit();??
  • ????????????return?depart;??
  • ????????}?finally?{??
  • ????????????if?(s?!=?null)??
  • ????????????????s.close();??
  • ????????}??
  • ????}??
  • ??
  • ????static?Department?add()?{??
  • ????????Session?s?=?null;??
  • ????????Transaction?tx?=?null;??
  • ????????try?{??
  • ????????????Department?depart?=?new?Department();??
  • ????????????depart.setName("department?name");??
  • ??????????????
  • ????????????Employee?employee1?=?new?Employee();??
  • ????????????employee1.setName("employee1?name1");??
  • ??????????????
  • ????????????Employee?employee2?=?new?Employee();??
  • ????????????employee2.setName("employee2?name2");??
  • ??????????????
  • ????????????List<Employee>?list=?new?ArrayList<Employee>();??
  • ????????????list.add(employee1);?//1??
  • ????????????list.add(employee2);?//2??
  • ????????????depart.setEmps(list);??
  • ??????????????
  • ????????????s?=?HibernateUtil.getSession();??
  • ????????????tx?=?s.beginTransaction();??
  • ????????????s.save(depart);??
  • ????????????s.save(employee1);??
  • ????????????s.save(employee2);??
  • ????????????tx.commit();??
  • ????????????return?depart;??
  • ????????}?finally?{??
  • ????????????if?(s?!=?null)??
  • ????????????????s.close();??
  • ????????}??
  • ????}??
  • }??
  • ?執行測試類,控制臺打印如下信息:

    emps:[id=1 name=employee1 name1, id=2 name=employee2 name2]

    將測試類中注釋為1和注釋為2的語句對換順序后,重新執行,控制臺打印如下信息:

    emps:[id=2 name=employee2 name2, id=1 name=employee1 name1]

    再看數據庫表中的記錄,如下所示:

    mysql> select * from department;
    +----+-----------------+
    | id | name??????????? |
    +----+-----------------+
    |? 1 | department name |
    +----+-----------------+
    1 row in set (0.00 sec)

    mysql> select * from employee;
    +----+-----------------+-----------+-----------+
    | id | name??????????? | depart_id | order_col |
    +----+-----------------+-----------+-----------+
    |? 1 | employee1 name1 |???????? 1 |???????? 1 |
    |? 2 | employee2 name2 |???????? 1 |???????? 0 |
    +----+-----------------+-----------+-----------+
    2 rows in set (0.00 sec)

    說明使用List時,因為配置文件下增加了<list-index column="order_col" />對加入List集合的元素的順序進行記錄,測試結果表明,確實對加入順序進行了記錄。

    ?

    三、bag集合映射(使用bag集合映射時,注意實體類中還是使用java.util.List與之對應)

    ?? 如果在實體類中使用了List類型的屬性,而我們并不希望保證集合中元素的順序(保證集合中元素的順序會采用排序算法,因而會占用一些CPU資源,一定程序上影響性能),可以在配置文件中使用<bag>,它的使用與<list>唯一不同的就是不保證集合中元素的順序。

    在List集合映射的基礎上,只需將配置文件中list部分替換成bag即可,其余部分不用修改,Department.hbm.xml配置文件修改如下:

    Java代碼 ?
  • <bag?name="emps">??
  • ????????<key?column="depart_id"?/>??
  • ????????<one-to-many?class="Employee"/>??
  • ????????</bag>??
  • 將測試類中注釋為1和注釋為2的語句對換順序后執行,控制臺打印如下信息:

    emps:[id=1 name=employee1 name1, id=2 name=employee2 name2]

    說明已經不再保證它的元素加入的順序了。

    再看數據庫表中的記錄,如下所示:

    ?mysql> select * from department;
    +----+-----------------+
    | id | name??????????? |
    +----+-----------------+
    |? 1 | department name |
    +----+-----------------+
    1 row in set (0.00 sec)

    mysql> select * from employee;
    +----+-----------------+-----------+
    | id | name??????????? | depart_id |
    +----+-----------------+-----------+
    |? 1 | employee1 name1 |???????? 1 |
    |? 2 | employee2 name2 |???????? 1 |
    +----+-----------------+-----------+
    2 rows in set (0.00 sec)

    此時數據庫就少了記錄順序的那一列值了。

    ?

    四、Map集合映射

    Map集合屬性不僅需要映射屬性value,還需要映射屬性key。這里假設Employee的name屬性是唯一的,如下修改Employee.hbm.xml配置文件中的name屬性,設置unique='true':

    Java代碼 ?
  • <property?name="name"?unique="true"/>??
  • ?實體類Department如下:

    Java代碼 ?
  • public?class?Department?{??
  • ??
  • ????private?int?id;??
  • ????private?String?name;??
  • ????private??Map<String,?Employee>?emps;??
  • //setter和getter方法??
  • ??
  • }??
  • ?修改Department.hbm.xml配置文件如下:

    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?package="com.reiyen.hibernate.domain">??
  • ????<class?name="Department">??
  • ????????<id?name="id">??
  • ????????????<generator?class="native"?/>??
  • ????????</id>??
  • ????????<property?name="name"?/>??
  • ????????<map?name="emps">??
  • ????????????<key?column="depart_id"?/>??
  • ????????????<map-key?type="string"?column="name"?/>??
  • ????????????<one-to-many?class="Employee"?/>??
  • ????????</map>??
  • ????</class>??
  • </hibernate-mapping>??
  • ?將測試類下如下注釋部分(即List部分)替換,改成Map重新進行測試:

    Java代碼 ?
  • //List<Employee>?list=?new?ArrayList<Employee>();??
  • //??????????list.add(employee2);??
  • //??????????list.add(employee1);??
  • ????????????Map<String,Employee>?emps?=?new?HashMap<String,Employee>();??
  • ????????????emps.put(employee1.getName(),?employee1);??
  • ????????????emps.put(employee2.getName(),?employee2);??
  • ????????????depart.setEmps(emps);??
  • ?測試結果如下:

    emps:{employee1 name1=id=1 name=employee1 name1, employee2 name2=id=2 name=employee2 name2}(紅色標記部分為key部分)

    數據庫表中記錄如下所示(未發生變化):

    mysql> select * from department;
    +----+-----------------+
    | id | name??????????? |
    +----+-----------------+
    |? 1 | department name |
    +----+-----------------+
    1 row in set (0.00 sec)

    mysql> select * from employee;
    +----+-----------------+-----------+
    | id | name??????????? | depart_id |
    +----+-----------------+-----------+
    |? 1 | employee1 name1 |???????? 1 |
    |? 2 | employee2 name2 |???????? 1 |
    +----+-----------------+-----------+
    2 rows in set (0.00 sec)

    五、array(數組)映射

    將實體類Department修改如下:

    Java代碼 ?
  • private?Employee[]?emps;??
  • ?Department.hbm.xml修改如下:

    Java代碼 ?
  • <array?name="emps">??
  • ????????????<key?column="depart_id"?/>??
  • ????????????<list-index?column="order_col"?/>??
  • ????????????<one-to-many?class="Employee"/>??
  • ????????????</array>??
  • ?測試類修改如下:

    Java代碼 ?
  • Employee[]?emps=?new?Employee[2];??
  • ????????????emps[0]?=?employee2;??
  • ????????????emps[1]?=?employee1;??
  • ????????????depart.setEmps(emps);??
  • ? Java代碼 ?
  • for(int?i?=?0;?i?<?depart.getEmps().length;?i++){??
  • ????????????????System.out.println(depart.getEmps()[i]);??
  • ????????????}??
  • ?測試結果如下所示,控制臺打印結果:

    id=2 name=employee2 name2
    id=1 name=employee1 name1

    數據庫表中記錄:

    mysql> select * from department;
    +----+-----------------+
    | id | name??????????? |
    +----+-----------------+
    |? 1 | department name |
    +----+-----------------+
    1 row in set (0.00 sec)

    mysql> select * from employee;
    +----+-----------------+-----------+-----------+
    | id | name??????????? | depart_id | order_col |
    +----+-----------------+-----------+-----------+
    |? 1 | employee1 name1 |???????? 1 |???????? 1 |
    |? 2 | employee2 name2 |???????? 1 |???????? 0 |
    +----+-----------------+-----------+-----------+
    2 rows in set (0.00 sec)

    總結:

    集合映射(set,list,array,bag,map)這些集合類都是Hibernate實現的類和JAVA中的集合不完全一樣,set,list,map
    分別和JAVA中的Set,List,Map接口對應,bag映射成JAVA的List;這些集合的使用和JAVA集合中對應的接口基本一致;在JAVA的實體類中集合只能定義成接口,不能定義成具體類,因為集合會在運行時被替換成Hibernate的實現。除了Set和Bag之外的所有集合類型都有一個索引(index)字段,這個字段映射到一個數組或者List的索引或者Map的key。Map的索引的類型可以是任何基本類型, 實體類型或者甚至是一個組合類型(但不能是一個集合類型)。數組和list的索引肯定是整型,integer。在Hibernate配置文件中使用 <index>, <index-many-to-many>, <composite-index> 或者<index-many-to-any>等元素來映射索引。集合的簡單使用原則:大部分情況下用set,需要保證集合中的順序時用list,想用java.util.List又不需要保證順序時用bag.

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的hibernate 集合类(Collections)映射的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 欧美精品不卡 | av在线不卡免费看 | 国产吞精囗交免费视频网站 | 精品亚洲国产成av人片传媒 | www.黄色网址 | 二区三区在线观看 | 97人人干| 色偷偷网站 | 国产毛片久久久久久 | 色婷婷色婷婷 | 免费观看日本 | 国产精品外围 | 波多野结衣免费观看视频 | 国产一级做a爱片久久毛片a | 国产精品三级在线观看无码 | 中文字幕人妻一区二区三区在线视频 | 日韩三级成人 | 91精品视频免费看 | 成人国产精品一区 | 日本肉体xxxⅹ裸体交 | 在线a毛片 | 禁断介护av一区二区 | 91欧美精品| 久久经典 | 欧美h视频在线观看 | 牛牛澡牛牛爽一区二区 | 天天伊人网 | 一区二区免费在线播放 | 少妇2做爰交换朴银狐 | 欧美人体视频一区二区三区 | 91啪国产在线 | 欧美日韩一区二区三区69堂 | www.嫩草.com | 99精品久久| 国产香蕉精品视频 | 欧美成人精品激情在线观看 | 亚洲成人国产 | 激情噜噜 | 亚洲狠狠 | 神马午夜伦理影院 | 在线免费精品视频 | 三级4级全黄60分钟 成人自拍视频 | 天堂av资源网| 伊人网大| 国产成人午夜高潮毛片 | 欧美成在线视频 | 日本午夜网| 人妻精品无码一区二区三区 | 中文久久乱码一区二区 | аⅴ资源天堂资源库在线 | 成人精品三级av在线看 | 日韩电影中文字幕在线观看 | 奇米四色网 | 大桥未久av在线 | 综合天堂av久久久久久久 | 日本特级淫片 | 蜜臀aⅴ免费一区二区 | 97久草 | 久久午夜夜伦鲁鲁片无码免费 | 色超碰 | 国产欧美日韩视频在线观看 | 葵司免费一区二区三区四区五区 | 精品国产三级 | 久久精品视频免费播放 | 91偷拍视频 | 偷偷在线观看免费高清av | 六月激情婷婷 | 91视频专区| 亚洲爽爽网 | 人妻 日韩精品 中文字幕 | 一区二区高清 | 亚洲精品xxxxx| 久久久久国产视频 | 亚洲粉嫩| 99色国产 | 亚洲欧美一区二区三区四区五区 | 天天影视亚洲 | 亚洲欧洲在线视频 | 日韩av在线观看免费 | 久久午夜片 | 91久久久久久久久 | av无码精品一区二区三区 | 成人av网站在线观看 | 人妖和人妖互交性xxxx视频 | 伊人久久久久久久久久 | 视频在线看 | 草草国产 | 黄频在线看 | 国产理伦 | 亚洲性图av| 奇米四色在线观看 | 涩涩成人| 国产乱人伦精品 | 国产色图片 | 成人动漫在线观看免费 | 亚洲精品在线视频观看 | 国产真人真事毛片 | 最新中文字幕免费视频 | 精品电影一区二区 |