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


先說一段廢話吧,本打算每天把所學的知識總結為博客的,但是昨天為什么沒有寫呢?沒有學習嗎?No,那是為什么?貪玩,對,這位同學說對了,老實說昨天感覺身體不怎么舒服,大家都知道,這其實就是為自己懶找借口,好吧,廢話先嘮到這兒,下面進入正題。


先說說概念吧

在持久化類中,有時會使用到值類型的對象屬性,所謂值類型的對象,是指它對應的類沒有對象標識符屬性,也就是我們在前面所說的OID,只能作為一個持久化類的屬性使用。如果持久化類中一個值類型的集合,那么就需要一張額外的數據庫表來保存這個值類型集合的數據,這張表被稱為集合表。

需要注意的一點是,hibernate3.0以后開始支持大部分重要的JDK集合接口映射,當然,現在的開發基本上都是使用3.0以后的版本吧,

為此,我們在項目中新建一個實體類吧,我取名StudentSet.java,給它簡單地賦予幾個屬性,其中比較特別的屬性就是hoppy屬性,它是一個Set集合類型的,表現為一多關系:

package com.joe.entity;

import java.util.Set;

/**
 * 
 * @author Joe
 * StudentSet java bean
 */
public class StudentSet {
    
    private int id;
    private String name;
    private int age;
    private Set<String> hobby;
    
    /**
     * 無參的構造函數
     */
    public StudentSet(){
        
    }
    
    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 Set<String> getHobby() {
        return hobby;
    }
    public void setHobby(Set<String> hobby) {
        this.hobby = hobby;
    }

}

在配置實體關心映射文件的時候,要特別注意對於set標簽的配置:<set>元素用來映射java.util.Set類型的屬性,常用的屬性和子元素有:

  1. name屬性:對應實體類中Set集合屬性
  2. table屬性:當前Set集合所對應的表結構
  3. <key>子元素:Set集合對應的表結構的外鍵列
  4. <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.StudentSet" table="stu_set_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>
        
        <set name="hobby" table="hobby_tab">
            <key column="student_id"></key>
            <element type="string" column="hobby"></element>
        </set>
        
    </class>
</hibernate-mapping>

其中key是hobby_tab的外鍵,element元素標簽是映射到數據庫中的集合的字段,另外,一定要為element標簽設置type屬性,否則是會拋異常的。編寫好了過后,不要忘了在hibernate.cfg.xml文件中添加映射,接下來,在test文件夾下的測試包中新建一個StudentSetTest.java測試類,在該類下,先添加下面的方法:

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

這個方法就不介紹了,執行該方法,看看hibernate都做了些什么?

QQ截圖20150808105728

可以發現,除了創建stu_set_tab表以外,還創建了一張名為hobby_tab的表,並且把student_id設置為hobby_tab的外鍵。

測試添加

緊跟上面的步伐,添加一個add()方法:

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

調用session的save()方法,測試該方法,在看看hibernate又為我們做了什么?

QQ截圖20150808110600

有點可惜,屏幕不夠大,看不完整,但思路是完整的,這幾句sql還是好理解的,就是簡單的插入操作,不再多言。

get()方法

這個測試更有趣一點:

/**
     * 查詢方法
     */
    @Test
    public void findAll(){
        Transaction tx=null;
        Session session=null;
        try{
            session=HibernateUtils.getSession();
            tx=session.beginTransaction();
            
            StudentSet stu=(StudentSet)session.get(StudentSet.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);
        }
    }

在次測試,看看控制台的輸出信息:

QQ截圖20150808111231

咦,為什么沒有查詢hobby_tab表呢?從上面的程序代碼中,我們並沒有訪問hobby屬性,改進程序代碼,添加訪問hobby屬性的代碼:

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

再次測試,結果應該都能猜到的,

QQ截圖20150808111739

如我們所料,hibernate執行了兩條sql語句。先根據id查詢學習的基本信息,再根據id在hobby_tab中查詢對應的數據。前面不是說過了嗎?只有訪問對象的非對象表示符(OID)屬性的時候,才會發起select語句,體現了hibernate的延遲加載、懶加載的特性。

好吧,把昨天的博客補上了,稍稍有點簡陋,當然還有很多沒有總結到的,也還有很多需要修正的,希望園子里的大神們可以給我提些意見和建議。


免責聲明!

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



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