天天看點

二、Hibernate的基本元素

隻需選擇一種形式的配置方式, 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 name="connection.password">root</property>

<property name="connection.driver_class">

org.gjt.mm.mysql.Driver

<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

可以選擇JDBC配置或者JNDI中的一種:

JDBC配置項:

dialect ---- 資料庫擴充卡, 每個資料庫略有不同

connection.driver_class --- 資料庫驅動類

connection.url --- 資料庫URL

connection.username --- 資料庫使用者名

connection.password --- 資料庫登陸密碼(對應的)

JNDI配置項:

dialect ---- 資料庫擴充卡, 同上

connection.datasource ---資料庫JNDI名稱

connection.username --- 資料庫使用者名, 同上

connection.password --- 資料庫登陸密碼(對應的) , 同上

目前Hibernate支援的4種連接配接池元件, 除了Hibernate預設的都需要指出hibernate.connection.provider_class.

hibernate預設的(hibernate.properties檔案為例):

hibernate.connection.pool_size 2

C3P0

Dbcp(推薦)

Proxool

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

為了擷取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);

SessionFactory顧名思義, 就是session的工廠類. 建立SessionFactory的執行個體就是調用已經裝載了配置資訊的Configuration對象的buildSessionFactory()方法:

SessionFactory sessionFactory = config.buildSessionFactory();

Hibernate2中buildSessionFactory()方法聲明了抛出異常.

SessionFactory對象中儲存了配置資訊. 如果要使用多個資料庫, 需要針對每個資料庫分别建立對應的SessionFactory執行個體, 如果需要動态改變config檔案, 則需要動态重建SessionFactory的執行個體.

SessionFactory中還儲存了二級資料緩存和Statement Pool, 它是線程安全的, 是以一個資料庫的SessionFactory一般作為單執行個體存在.

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() {

// SESSIONCONTAINER.set(null);

} else {

se.close();

在WebApplication中為了更好的管理Session的生命周期, 可以把靜态ThreadLocal對象定義在過濾器中, 在進入過濾器時調用其set(新的Session); 執行doFilter後, 在調用get方法去除Session并進行關閉.在業務操作中,統一用過濾器的靜态ThreadLocal擷取Session, 就保證了每一個request對象隻能使用一個獨立的Session.

由于一些EJB可能會運作在同一個事務但不同線程的環境中, 是以這個方法不能照搬到EJB環境中.建議在托管環境中,将SessionFactory綁定到JNDI上.

本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1080833