hibernate註解自動生成數據表

按習慣來說,一般系統開發都是從數據庫開始設計的。但從面向對象開發的角度,系統的設計應該基於對象模型的設計之上,主要考慮對象的設計和邏輯,然後按照對象模型生成數據庫結構,利用hibernate的SchemaExport對象可以方便的實現這一點。另外,使用註解也省卻了很多繁雜的配置工作,下面對hibernate註解自動生成數據表的過程做一個詳細描述。

       一、環境搭載

      下載了最新的hibernate-release-4.0.0.CR7.zip,導入required包,這個例子是基於MySql數據庫,因此還需要mysql-connector-java-5.1.5.jar

       二、配置

       hibernate的配置文件可以使用xml或者properties,這裏使用的xml:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-configuration PUBLIC  
  3. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  5.   
  6. <hibernate-configuration>  
  7. <session-factory>  
  8.     <!-- 各屬性的配置-->  
  9.     <!--爲true表示將Hibernate發送給數據庫的sql顯示出來-->  
  10.     <property name="show_sql">true</property>  
  11.     <!-- SQL方言,這邊設定的是MySQL -->  
  12.     <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>  
  13.     <!-- 一次讀的數據庫記錄數 -->  
  14.     <property name="jdbc.fetch_size">50</property>  
  15.     <!-- 設定對數據庫進行批量刪除 -->  
  16.     <property name="jdbc.batch_size">30</property>  
  17.     <!--驅動程序-->  
  18.     <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
  19.     <!-- JDBC URL -->  
  20.     <property name="connection.url">jdbc:mysql://localhost/fight_game?characterEncoding=utf-8</property>  
  21.     <!-- 數據庫用戶名-->  
  22.     <property name="connection.username">root</property>  
  23.     <!-- 數據庫密碼-->  
  24.     <property name="connection.password">root</property>  
  25.   
  26.         <!-- 使用本地事務jdbc事務,如果是使用全局jta事務,則需要配置爲jta-->  
  27.   
  28.   <property name="current_session_context_class">thread</property>  
  29. <mapping class="cn.com.model.User" />  
  30. </session-factory>  
  31. </hibernate-configuration>    

        關於current_session_context_class配置項:

        通過hibernate操作數據庫時,主要是通過session實現的,session可以簡單的視爲對數據庫的一個鏈接,有它的生命週期。獲取session在SessionFactory裏有兩個方法,getCurrentSession()和openSession(),後者每次都會新建一個session,它們的區別:

       1 、getCurrentSession創建的session會綁定到當前線程,而openSession不會。       

        2 、getCurrentSession創建的線程會在事務回滾或事物提交後自動關閉,而openSession必須手動關閉

        因此,通常使用getCurrentSession()會方便高效一些,但需要在配置文件中配置current_session_context_class,可以有兩個取值jta或者thread。

        引用: 使用Hibernate的大多數應用程序需要某種形式的“上下文相關的” session,特定的session在整個特定的上下文範圍內始終有效。然而,對不同類型的應用程序而言,要爲什麼是組成這種“上下文”下一個定義通常是困難的;不同的上下文對“當前”這個概念定義了不同的範圍。在3.0版本之前,使用Hibernate的程序要麼採用自行編寫的基於 ThreadLocal的上下文session,要麼採用HibernateUtil這樣的輔助類,要麼採用第三方框架(比如Spring或Pico),它們提供了基於代理(proxy)或者基於攔截器(interception)的上下文相關session。        

        從3.0.1版本開始,Hibernate增加了SessionFactory.getCurrentSession()方法。一開始,它假定了採用JTA事務,JTA事務定義了當前session的範圍和上下文(scope and context)。Hibernate開發團隊堅信,因爲有好幾個獨立的JTA TransactionManager實現穩定可用,不論是否被部署到一個J2EE容器中,大多數(假若不是所有的)應用程序都應該採用JTA事務管理。基於這一點,採用JTA的上下文相關session可以滿足你一切需要。       

        更好的是,從3.1開始,SessionFactory.getCurrentSession()的後臺實現是可拔插的。因此,我們引入了新的擴展接口 (org.hibernate.context.CurrentSessionContext)和新的配置參數 (hibernate.current_session_context_class),以便對什麼是“當前session”的範圍和上下文(scope and context)的定義進行拔插。       

        請參閱 org.hibernate.context.CurrentSessionContext接口的Javadoc,那裏有關於它的契約的詳細討論。它定義了單一的方法,currentSession(),特定的實現用它來負責跟蹤當前的上下文session。Hibernate內置了此接口的兩種實現。      

org.hibernate.context.JTASessionContext - 當前session根據JTA來跟蹤和界定。這和以前的僅支持JTA的方法是完全一樣的。詳情請參閱Javadoc。                                  org.hibernate.context.ThreadLocalSessionContext - 當前session通過當前執行的線程來跟蹤和界定。詳情也請參閱Javadoc。      

        這兩種實現都提供了“每數據庫事務對應一個session”的編程模型,也稱作每次請求一個session。Hibernate session的起始和終結由數據庫事務的生存來控制。假若你採用自行編寫代碼來管理事務(比如,在純粹的J2SE,或者 JTA/UserTransaction/BMT),建議你使用Hibernate Transaction API來把底層事務實現從你的代碼中隱藏掉。如果你在支持CMT的EJB容器中執行,事務邊界是聲明式定義的,你不需要在代碼中進行任何事務或 session管理操作。請參閱第 11 章 事務和併發一節來閱讀更多的內容和示例代碼。        hibernate.current_session_context_class 配置參數定義了應該採用哪個org.hibernate.context.CurrentSessionContext實現。注意,爲了向下兼容,如果未配置此參數,但是存在org.hibernate.transaction.TransactionManagerLookup的配置,Hibernate會採用org.hibernate.context.JTASessionContext。一般而言,此參數的值指明瞭要使用的實現類的全名,但那兩個內置的實現可以使用簡寫,即"jta"和"thread"。

         在 SessionFactory 啓動的時候, Hibernate 會根據配置創建相應的 CurrentSessionContext ,在 getCurrentSession() 被調用的時候,實際被執行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 執行時,如果當前 Session 爲空, currentSession 會調用 SessionFactory 的 openSession 。所以 getCurrentSession() 對於 Java EE 來說是更好的獲取 Session 的方法。

         三、編寫持久化對象

  1. package cn.com.model;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.GeneratedValue;  
  8. import javax.persistence.GenerationType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.Table;  
  11.   
  12. @Entity  
  13. @Table(name="t_user")  
  14. public class User implements Serializable{  
  15.     /** 
  16.      *  
  17.      */  
  18.     private static final long serialVersionUID = 1L;  
  19.   
  20.     private long id;  
  21.   
  22.     private String name;  
  23.       
  24.     @Id  
  25.     @GeneratedValue(strategy=GenerationType.IDENTITY)  
  26.     public long getId() {  
  27.         return id;  
  28.     }  
  29.   
  30.     public void setId(long id) {  
  31.         this.id = id;  
  32.     }  
  33.   
  34.     @Column(name="name",length=50)  
  35.     public String getName() {  
  36.         return name;  
  37.     }  
  38.   
  39.     public void setName(String name) {  
  40.         this.name = name;  
  41.     }  
  42.       
  43. }  
        所有對象編寫完後,需要在配置文件中配置,這裏爲:<mapping class="cn.com.model.User" />

        四、測試

       Configuration configuration = new AnnotationConfiguration();
        configuration.configure();
        SchemaExport export = new SchemaExport(configuration);
        export.execute(true, true, false, true);
        SessionFactory factory = configuration.buildSessionFactory();
//        Session session = factory.openSession();
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        User user = new User();
        user.setName("成都");
        session.save(user);
        session.getTransaction().commit();
//        session.close();

        關於SchemaExport對象有幾個方法生成數據庫結構。

       1、create(boolean script,boolean export)

        script:是否在控制檯打印DDL語句,export爲true時,會先執行drop再根據持久化對象create數據表,可能造成數據丟失,爲false時,數據庫需要先建立對應的數據表,否則會找不到表而報錯,不會造成數據丟失。

        2、drop(boolean script,boolean export)

        script:是否在控制檯打印DDL語句,export爲true時,會執行drop操作,爲false時不執行

        3、execute(boolean script, boolean export,boolean justDrop, boolean justCreate)

        當export爲true時,justDrop爲false,justCreate爲true,如果對應的數據表不存在,則create,如果存在則不執行create操作

        當export爲true時,justDrop爲true,justCreate爲false,執行drop操作

         因此,要新建數據表,最好使用create(true,true);

        來自:http://blog.csdn.net/leiswpu/article/details/7077642

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章