一. Hibernate的基本元素
Configuration---hibernate.cfg.xml
1. hibernate.cfg.xml 或 hibernate.properties 預設的配置檔案
只需選擇一種形式的配置方式, properties形式的檔案不配置mapping子節點,且不使用xml的格式:
一個典型的xml配置檔案如下:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.username">root</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
org.gjt.mm.mysql.Driver
</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping resource="cn/thinkmore/hibernate/pojo/tuser.hbm.xml" />
<!—
other mapping element...
-->
</session-factory>
</hibernate-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernate3.pojo.Tuser" table="t_user">
<id column="ID" name="id" type="java.lang.String">
<generator class="uuid.hex" />
</id>
<property column="NAME" name="name" type="java.lang.String" />
<property column="EMAIL" name="email" type="java.lang.String" />
</class>
</hibernate-mapping>
對應的hibernate.properties檔案為:
connection.username root
connection.url jdbc:mysql://localhost:3306/test
dialect org.hibernate.dialect.MySQLDialect
connection.password root
connection.driver_class org.gjt.mm.mysql.Driver
show_sql true
2. 配置檔案-----資料庫連線配置
可以選擇JDBC配置或者JNDI中的一種:
JDBC配置項:
dialect ---- 資料庫介面卡, 每個資料庫略有不同
connection.driver_class --- 資料庫驅動類
connection.url --- 資料庫URL
connection.username --- 資料庫使用者名稱
connection.password --- 資料庫登陸密碼(對應的)
JNDI配置項:
dialect ---- 資料庫介面卡, 同上
connection.datasource ---資料庫JNDI名稱
connection.username --- 資料庫使用者名稱, 同上
connection.password --- 資料庫登陸密碼(對應的) , 同上
3. 配置檔案-----資料庫連線池配置
目前Hibernate支援的4種連線池元件, 除了Hibernate預設的都需要指出hibernate.connection.provider_class.
hibernate預設的(hibernate.properties檔案為例):
hibernate.connection.pool_size 2
C3P0
Dbcp(推薦)
Proxool
4. Transaction(事務管理)
hibernate.transaction.factory_class配置Transaction例項工廠類二選一.
JDBC的事務處理機制:
hibernate.transaction.factory_class org.hibernate.transaction. JDBCTransaction
使用JTA
hibernate.transaction.factory_class org.hibernate.transaction. JTATransaction
jta.UserTransaction jta/usertransaction
配置, Session相關
5. Configuration類(org.hibernate.cfg.Configuration類)
為了獲取SessionFactory, 一般只需執行一次. xml形式的配置檔案比較方便:
Configuration config = new Configuration().configure();
也可以指定一個檔案進行載入,而不使用預設的hibernate.cfg.xml檔案,
java.io.File file = new java.io.File(“…..”);
Configuration config = new Configuration().configure(file);
對應properties形式的配置方式必須手工載入對映檔案,比如:
Configuration config=new Configuration();
config.addClass(TUser.class);
6. SessionFactory(org.hibernate.SessionFactory介面)
SessionFactory顧名思義, 就是session的工廠類. 建立SessionFactory的例項就是呼叫已經裝載了配置資訊的Configuration物件的buildSessionFactory()方法:
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Hibernate2中buildSessionFactory()方法宣告瞭丟擲異常.
SessionFactory物件中儲存了配置資訊. 如果要使用多個資料庫, 需要針對每個資料庫分別建立對應的SessionFactory例項, 如果需要動態改變config檔案, 則需要動態重建SessionFactory的例項.
SessionFactory中還儲存了二級資料快取和Statement Pool, 它是執行緒安全的, 所以一個資料庫的SessionFactory一般作為單例項存在.
7. 得到Session, Session的執行緒區域性化
Session newSession = sessionFactory.openSession();
Session代表Hibernate的會話, 作用就像JDBC的Conection物件. Hibernate2的find方法已經被廢除.
Session是非執行緒安全的, 所以不應該對同一個Session例項進行多執行緒同時呼叫.
HibernateUtil和靜態SessionFactory一起工作, 由ThreadLocal管理Hibernate Session。通過ThreadLocal型別來實現Session的執行緒獨立. ThreadLocal在JVM內部維護一個Map, key是當前的執行緒物件, value是在當前執行緒中呼叫ThreadLocal物件的set方法時傳遞的引數. 當呼叫ThreadLocal物件的get方法時, ThreadLocal物件會把當前執行緒物件的引用作為key從Map中取出繫結的物件.
package cn.thinkmore.hibernate.session;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil{
private static SessionFactory sessionFactory;
static {
sessionFactory = new Configuration().configure().buildSessionFactory();
}
private static final ThreadLocal<Session> SESSIONCONTAINER = new ThreadLocal<Session>();
public static Session currentSession() {
Session se = (Session) SESSIONCONTAINER.get();
if (null == se) {
se = sessionFactory.openSession();
SESSIONCONTAINER.set(se);
}
return se;
}
public static void closeSession() {
Session se = (Session) SESSIONCONTAINER.get();
if (null == se) {
// SESSIONCONTAINER.set(null);
} else {
se.close();
}
}
}
在WebApplication中為了更好的管理Session的生命週期, 可以把靜態ThreadLocal物件定義在過濾器中, 在進入過濾器時呼叫其set(新的Session); 執行doFilter後, 在呼叫get方法去除Session並進行關閉.在業務操作中,統一用過濾器的靜態ThreadLocal獲取Session, 就保證了每一個request物件只能使用一個獨立的Session.
由於一些EJB可能會執行在同一個事務但不同執行緒的環境中, 所以這個方法不能照搬到EJB環境中.建議在託管環境中,將SessionFactory繫結到JNDI上.