Hibernate學習筆記(二)基本配置

Hibernate可以使用XML檔案或properties檔案來配置SessionFactory,默認的配置文件名稱爲hibernate.cfg.xml或hibernate.properties,使用下面的方式來讀入文件以配置Hibernate:

Configurationconfig = new Configuration().configure();

當您使用new建構Configuration對象時,會讀取Classpath路徑下的 hibernate.properties,如果您呼叫Configuration的configure()方法沒有指定路徑與文件名時,則會再讀取Classpath路徑下的hibernate.cfg.xml,如果有與hibernate.properties相同的屬性設定,則hibernate.cfg.xml中的設定會覆蓋hibernate.properties中的設定。


默認的XML配置文件名稱是hibernate.cfg.xml,您也可以自行指定檔案路徑與名稱,例如:

Configuration config = newConfiguration().configure("/config/db.cfg.xml");

在取得Configuration實例後,您還可以撰寫程序的方式來設定新的屬性,或甚至讀入另一個HBM配置文件案,例如:

Configuration config = new Configuration
                             .configure()
                             .setProperty(Environment.FORMAT_SQL,"true")
                            .addResource("Room.hbm.xml");

所有的屬性設定,在Hibernate中都對應於Environment類別中的一個靜態成員,例如format_sql就對 應於Enviromnent.FORMAT_SQL,connection.driver_class就對應於Environment.DRIVER。


爲了配置文件時更有彈性,您可以使用系統屬性來指定,例如在hibernate.cfg.xml中撰寫:

...
 

 <property name="show_sql">${displaysql}</property>
    <!-- 將顯示的SQL排版,方便觀看 -->
...


如此,若在啓動Java時,加上-Ddisplaysql=true,則可觀看到產生的SQL語句。

使用屬性檔案進行配置時,文件名是hibernate.properties,必須放置在Classpath之下,一個例子如下:

  • hibernate.properties

hibernate.show_sql = true
hibernate.format_sql = true
hibernate.dialect = org.hibernate.dialect.MySQLDialect 
hibernate.connection.driver_class = com.mysql.jdbc.Driver 
hibernate.connection.url = jdbc:mysql://localhost/demo
hibernate.connection.username = caterpillar 
hibernate.connection.password = 123456

由於properties檔案中不包括映像文件的名稱,爲了要取得對象至資 料庫表格的映像文件,您必須在程序中如下加載:

Configuration cfg = new Configuration().addClass(User.class).addClass(Room.class);

第一個addClass()加入位於Classpath根目錄下的User.hbm.xml,第二個addClass()加入Room類別的映像文件,該 文件必須位於與User類別同一個目錄,也就是/Room.hbm.xml。

在Hibernate下載文件中的etc目錄下,有hibernate.cfg.xml與hibernate.properties可供設定參考。

Configuration的實例管理Hibernate的配置訊息,通常用於建立SessionFactory,例如:

SessionFactory sessionFactory =config.buildSessionFactory();
SessionFactory一旦建立,就被賦予當時Configuration的配置訊息,之後您改變Configuration並不會影響已建立的 SessionFactory實例,如果對Configuration改動後,則要建立一個新的SessionFactory實例,新的實例中會包括新的配置訊息, SessionFactory是被設計爲「線程安全的」(Thread-safe)。


每個內建的Hibernate類型,在 org.hibernate.Hibernate類別中都有對應的常數,例如Hibernate.STRING。基本上,Hibernate會使用 Reflection自動找出屬性的數據型態,所以type屬性在使用POJO時可以省略不設,如果有特別設定,則Hibernate就不用使用 Reflection來找出類型,不過在使用 態模型(Dynamic Model,type屬性則是必須設定的,用以得知動態模型中應放入哪種類型的對象。

<generator>設定主鍵的生成方式,可以設定"native"表示由Hibernate自動根據Dialect選擇 採用 identity、hilo、sequence等作爲主鍵生成方式,也可以考慮採用uuid由Hibernate根據128位UUID算法(128- bit UUID algorithm)生成16進位制數值,並編碼爲32位長度的字符串,還有其它的主鍵生成方式,可以參考官方手冊的Generator 說明。

您可以在<hibernate-mapping>上設定package屬性,如此一來,文件中要設置類別名稱時,就不用寫出完整的package,例如:

<hibernate-mapping package="onlyfun.caterpillar">
    <!--類別名稱與表格名稱映像-->
    <classname="User" table="user">
       ....
   </class> 
</hibernate-mapping>

在使用HQL時,您可以只使用類別名稱來替代完整名稱:

// 相當於寫"from onlyfun.caterpillar.User"
Query query = session.createQuery("fromUser"); 
這是Hibernate的auto-import功能,然而如果在不同的package下都有User類別,則Hibernate將無從得知是要使用哪個User類別,您可以在<hibernate-mapping>上設定auto-import屬性爲false,關閉auto-import功能,並在HQL中撰寫完整的類別名稱。


另一種解決的方式,是在<hibernate-mapping>中使用<import>設定別名,例如:

<hibernate-mapping> 
    <importclass="onlyfun.caterpillar.User" rename="DemoUser"/>
</hibernate-mapping>

之後在指定HQL中,即可使用這個別名:

Query query = session.createQuery("from DemoUser"); 

對於一些不能爲空的屬性,可以在<property>上加上not-null屬性爲true,如此Hibernate可以直接檢查屬性是否爲null,而不用等進入到數據庫中再作檢查。


如果有某個屬性,其值取決於表格字段自己產生的值,而非程序中主動設定的值,例如數據新增時,會由數據庫產生新增時的時間,而這個值想要主動提取至對象的對應屬性,則可以在<property>上設定generated屬性,例如:

...   

 <propertyname="time" column="time" 
             insert="false" update="false"generated="always"/>
...


如上設定之後,當對象儲存時,time屬性並不會參與儲存,而是由數據庫產生time域值,再SELECT出來設定給time屬性,由於並非實際要儲存屬性,所以設定insert爲false,而由於這個字段由數據庫維護,所以update設定爲false。

如果對象上有個屬性,實際上並沒有字段與之對應,您只是想藉由數據庫中的字段查詢來取得,例如使用COUNT函式來取得所有的筆數,則您可以使用formula屬性,例如:

... 

   <propertyname="average" formula="(SELECT AVG(u.age) FROM T_USERu)"/>
...

 


發佈了50 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章