如何理解Hibernate中的HibernateSessionFactory類

 

 

package com.zz.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
 * Configures and provides access to Hibernate sessions, tied to the
 * current thread of execution.  Follows the Thread Local Session
 * pattern, see {@link http://hibernate.org/42.html }.
 */
public class HibernateSessionFactory {

    /** 
     * Location of hibernate.cfg.xml file.
     * Location should be on the classpath as Hibernate uses  
     * #resourceAsStream style lookup for its configuration file. 
     * The default classpath location of the hibernate config file is 
     * in the default package. Use #setConfigFile() to update 
     * the location of the configuration file for the current session.   
     */
	private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static org.hibernate.SessionFactory sessionFactory;
	
    private static Configuration configuration = new Configuration();
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
    private static String configFile = CONFIG_FILE_LOCATION;

	static {
    	try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory();
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
    }
    private HibernateSessionFactory() {
    }
	
	/**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws HibernateException
     */
    public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get();

		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				rebuildSessionFactory();
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}

        return session;
    }

	/**
     *  Rebuild hibernate session factory
     *
     */
	public static void rebuildSessionFactory() {
		try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory();
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
	}

	/**
     *  Close the single hibernate session instance.
     *
     *  @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

	/**
     *  return session factory
     *
     */
	public static org.hibernate.SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
     *  return session factory
     *
     *	session factory will be rebuilded in the next call
     */
	public static void setConfigFile(String configFile) {
		HibernateSessionFactory.configFile = configFile;
		sessionFactory = null;
	}
	/**
     *  return hibernate configuration
     *
     */
	public static Configuration getConfiguration() {
		return configuration;
	}

}

 

HibernateSessionFactory類是自定義的SessionFactory,名字能夠根據本身的喜愛來決定。這裏用的是HibernateSessionFactory,其內容及解釋。上述代碼是由myeclipse 自動生成的;也能夠根據本身的狀況寫出:html

package com.zz.util;
 
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
//在使用hibernate開發項目,請必定保證只有一個SessionFactory
//一個數據庫對應一個SessionFactory 對象.
final public class MySessionFactory {
 
    private static SessionFactory sessionFactory=null;
     
    private MySessionFactory(){
         
    }
     
    static{
         
        sessionFactory =new Configuration().configure("com/zz/config/hsp.cfg.xml").buildSessionFactory(); 
        System.out.println("sessionFactory 類型"+sessionFactory);
    }
     
    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }
     
}


 

Hibernate中,Session負責完成對象持久化操做。該文件負責建立Session對象,以及關閉Session對象。從該文件能夠看出,Session對象的建立大體須要如下3個步驟:java

① 初始化Hibernate配置管理類Configuration數據庫

② 經過Configuration類實例建立Session的工廠類SessionFactory數組

③ 經過SessionFactory獲得Session實例。緩存

³1. Configuration接口

Configuration負責管理Hibernate的配置信息。Hibernate運行時須要一些底層實現的基本信息。這些信息包括:數據庫URL、數據庫用戶名、數據庫用戶密碼、數據庫JDBC驅動類、數據庫dialect。用於對特定數據庫提供支持,其中包含了針對特定數據庫特性的實現,如Hibernate數據庫類型到特定數據庫數據類型的映射等。安全

使用Hibernate必須首先提供這些基礎信息以完成初始化工做,爲後續操做作好準備。這些屬性在Hibernate配置文件hibernate.cfg.xml中加以設定,當調用:session

Configuration config=new Configuration().configure();多線程

時,Hibernate會自動在目錄下搜索hibernate.cfg.xml文件,並將其讀取到內存中做爲後續操做的基礎配置。併發

³ 2. SessionFactory接口

SessionFactory負責建立Session實例,能夠經過Configuration實例構建SessionFactoryeclipse

Configuration config=new Configuration().configure();

SessionFactorysessionFactory=config.buildSessionFactory();

Configuration實例config會根據當前的數據庫配置信息,構造SessionFacory實例並返回。SessionFactory一旦構造完畢,即被賦予特定的配置信息。也就是說,以後config的任何變動將不會影響到已經建立的SessionFactory實例sessionFactory。若是須要使用基於變動後的config實例的SessionFactory,須要從config從新構建一個SessionFactory實例。

SessionFactory保存了對應當前數據庫配置的全部映射關係,同時也負責維護當前的二級數據緩存和Statement Pool。因而可知,SessionFactory的建立過程很是複雜、代價高昂。這也意味着,在系統設計中充分考慮到SessionFactory的重用策略。因爲SessionFactory採用了線程安全的設計,可由多個線程併發調用。

³3. Session接口

SessionHibernate持久化操做的基礎,提供了衆多持久化方法,如saveupdatedelete等。經過這些方法,透明地完成對象的增長、刪除、修改、查找等操做。

同時,值得注意的是,HibernateSession的設計是非線程安全的,即一個Session實例同時只可由一個線程使用。同一個Session實例的多線程併發調用將致使難以預知的錯誤。

Session實例由SessionFactory構建:

Configuration config=new Configuration().configure();

SessionFactorysessionFactory=config.buldSessionFactory();

Session session=sessionFactory.openSession();

³4. Transaction接口

TransactionHibernate中進行事務操做的接口,Transaction接口是對實際事務實現的一個抽象,這些實現包括JDBC的事務、JTA中的UserTransaction,甚至能夠是CORBA事務。之因此這樣設計是可讓開發者可以使用一個統一的操做界面,使得本身的項目能夠在不一樣的環境和容器之間方便地移值。事務對象經過Session建立。例如如下語句:

Transaction ts=session.beginTransaction();

³5. Query接口

Hibernate 2.x中,find()方法用於執行HQL語句。Hibernate 3.x廢除了find()方法,取而代之的是Query接口,它們都用於執行HQL語句。QueryHQL是分不開的。

Query query=session.createQuery(「fromtable where id=1」);

例如如下語句:

Query query=session.createQuery("fromtable whereid=?");

就要在後面設置其值:

Query.setString(0,"要設置的值");

上面的方法是經過「?」來設置參數,還能夠用「:」後跟變量的方法來設置參數,如上例能夠改成:

Query query=session.createQuery("fromtable whereid=:1");

Query.setString("kchValue","要設置的課程號值");

其使用方法是相同的,例如:

Query.setParameter(0,"要設置的值");

Query還有一個list()方法,用於取得一個List集合的示例,此示例中包括多是一個Object集合,也多是Object數組集合。例如:

Query query=session.createQuery("fromtable whereid=1");

List list=query.list();

相關文章
相關標籤/搜索