hibernate學習系列-----(7)hibernate對集合屬性的操作之List集合篇


今天要寫的內容其實不多,本打算將hibernate對集合的操作的內容直接歸結為一篇的,但想一想,還是分開寫的比較好,畢竟前面的已經發布出去來了,廢話不多說,開始吧!


依舊新建一個StudentList.java實體類,其他的屬性不變,只是將hobby屬性由Set集合類型變為List集合類型,還是把代碼貼出來吧,希望不要嫌煩

package com.joe.entity;

import java.util.List;

public class StudentList {
    
    private int id;
    private String name;
    private int age;
    
    private List<String> hobby;

    /**
     * 無參構造函數
     */
    public StudentList(){
        
    }
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getHobby() {
        return hobby;
    }

    public void setHobby(List<String> hobby) {
        this.hobby = hobby;
    }
    

}

接下來,大家都知道的,就是配置StudentList.hbm.xml對象關系映射文件了,先說說<list>標簽吧,<list>元素用來映射java.util.List類型的屬性,常用的屬性和子元素有:

  1. name屬性
  2. table屬性
  3. <key>子元素
  4. <list-index>子元素
  5. <element>子元素

照樣貼上代碼:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 一個class標簽對應一個實體類,name屬性指定實體類名稱,table屬性指定關聯的數據庫表 -->
    <class name="com.joe.entity.StudentList" table="stu_list_tab">
        <!-- 主鍵 -->
        <id name="id" column="stu_id">
            <!-- 提供ID自增的策略  native會根據數據庫自行判斷 -->
            <generator class="native"></generator>
        </id>
        <!-- 其他屬性,name對應實體類的屬性,column對應關系型數據庫表的列 -->
        <property name="name" column="stu_name"></property>
        <property name="age" column="stu_age"></property>
        
        <list name="hobby" table="hobby_list_tab">
            <key column="student_id"></key>
            <list-index column="position"></list-index>
            <element type="string" column="hobby"></element>
        </list>
        
    </class>
</hibernate-mapping>

來解讀一下list標簽吧,<key>子元素和<element>子元素就不多講了,主要是<list-index>子元素,我查了一下資料,也可以使用<index>,因List集合是個有序可重復的集合,所以要使用<index-index column="position"/></list-index>(或者使用<index column="position"></index>) 來標明其順序。(position為hobby_list_tab表中附加字段),因此在插入更新時便需要維護position字段,否則索引設置錯誤,取出的數據就會出現空值情況。

如果<list>標簽配置了inverse="true"屬性, 則list的index則不會主動賦值,index列會產生空值,如果index列數據庫設置可以為空,則可以正常保存數據. 而用hibernate再去查詢對象數據時,會拋出null index column for collection: 此類錯誤.也就是說配置inverse為true的list,需要手動維護index列.感覺還是挺復雜的,有點兒攪。

當然,還可以使用<bag>(結合了List與Set)標簽來配置list集合屬性,可以重復且沒有順序的一種集合,是Hibernate提供的。HIbernate使用jdk的List模擬Bag。其配置與Hibernate映射list時基本相同。這里就不再討論來,畢竟這是是沖着list來的。

依舊建立一個StudentListTest.java測試類,先寫一個創建表結構的方法:

@Test
    public void createTable() {
        Configuration cfg = new Configuration().configure();
        SchemaExport se = new SchemaExport(cfg);
        se.create(true, true);
    }

執行該方法,看看hibernate的執行結果:

QQ截圖20150809105449

在創建hobby_list_tab表的時候,可以看到position字段配置來not null 屬性,這也體現來前面的list標簽的配置,更多的信息可以在其官方文檔了解,這里提供一個快捷通道:點擊這里

add()方法的測試:

/**
     * 添加的方法
     */
    @Test
    public void add(){
        Transaction tx=null;
        Session session=null;
        try{
            session=HibernateUtils.getSession();
            tx=session.beginTransaction();
            StudentList student=new StudentList();
            student.setName("zhangsan");
            student.setAge(20);
            
            List<String> list=new ArrayList<String>();
            list.add("basketball");
            list.add("swimming");
            
            student.setHobby(list);
            
            session.save(student);
            
            
            tx.commit();
        }catch(HibernateException he){
            if(tx!=null){
                tx.rollback();
            }
            he.printStackTrace();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }

執行該方法,看看控制台的輸出信息:

QQ截圖20150809110500

只有一點需要說明的,就是我在程序中並沒有為position膚質,那position字段中是否有值,如果有,為何值?打開mysql數據庫,一看便知:

QQ截圖20150809110912

哎,有值,這是hibernate提供的一種機制,它自動維護,只要你配置正確。還有一個問題需要注意,就是為什么是從0開始的而不是其他的值開始的呢?這就和我們的List集合相關聯,List的底層是一個動態的數組,所以添加元素時,下標是從0開始的。

findAll()方法的測試:

@Test
    public void findAll(){
        Transaction tx=null;
        Session session=null;
        try{
            session=HibernateUtils.getSession();
            tx=session.beginTransaction();
            
            StudentList stu=(StudentList)session.get(StudentList.class, 1);
            System.out.println(stu.getId()+stu.getName()+stu.getAge());
            
            
            
            tx.commit();
        }catch(HibernateException he){
            if(tx!=null){
                tx.rollback();
            }
            he.printStackTrace();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }

和以前測試差不多,先只訪問基本屬性,我想hibernate的執行動作大家都知道了,只會有一條select語句,不會去訪問hobby_list_tab表的,還是貼上圖吧:

QQ截圖20150809112027

接下來,添加訪問hobby屬性的代碼:

//訪問hobby屬性
            List<String> hobby=stu.getHobby();
            for(String str:hobby){
                System.out.println(str);
            }

相信結果大家還是知道的,依舊貼圖:

QQ截圖20150809112301

其實自我感覺這篇文章和上一篇文章有點重復,但是還不至於無聊致死,畢竟知識是一步一步學來的,接下來的一兩篇,節奏大概還是這樣的吧,各位看官,不要嫌我啰嗦喲。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM