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 自動生成的;也可以根據自己的情況寫出:
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個步驟:
① 初始化Hibernate配置管理類Configuration。
② 通過Configuration類實例創建Session的工廠類SessionFactory。
③ 通過SessionFactory得到Session實例。
Configuration負責管理Hibernate的配置信息。Hibernate運行時需要一些底層實現的基本信息。這些信息包括:數據庫URL、數據庫用戶名、數據庫用戶密碼、數據庫JDBC驅動類、數據庫dialect。用於對特定數據庫提供支持,其中包含了針對特定數據庫特性的實現,如Hibernate數據庫類型到特定數據庫數據類型的映射等。
使用Hibernate必須首先提供這些基礎信息以完成初始化工作,為后續操作做好准備。這些屬性在Hibernate配置文件hibernate.cfg.xml中加以設定,當調用:
Configuration config=new Configuration().configure();
時,Hibernate會自動在目錄下搜索hibernate.cfg.xml文件,並將其讀取到內存中作為后續操作的基礎配置。
SessionFactory負責創建Session實例,可以通過Configuration實例構建SessionFactory。
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采用了線程安全的設計,可由多個線程並發調用。
Session是Hibernate持久化操作的基礎,提供了眾多持久化方法,如save、update、delete等。通過這些方法,透明地完成對象的增加、刪除、修改、查找等操作。
同時,值得注意的是,HibernateSession的設計是非線程安全的,即一個Session實例同時只可由一個線程使用。同一個Session實例的多線程並發調用將導致難以預知的錯誤。
Session實例由SessionFactory構建:
Configuration config=new Configuration().configure();
SessionFactorysessionFactory=config.buldSessionFactory();
Session session=sessionFactory.openSession();
Transaction是Hibernate中進行事務操作的接口,Transaction接口是對實際事務實現的一個抽象,這些實現包括JDBC的事務、JTA中的UserTransaction,甚至可以是CORBA事務。之所以這樣設計是可以讓開發者能夠使用一個統一的操作界面,使得自己的項目可以在不同的環境和容器之間方便地移值。事務對象通過Session創建。例如以下語句:
Transaction ts=session.beginTransaction();
在Hibernate 2.x中,find()方法用於執行HQL語句。Hibernate 3.x廢除了find()方法,取而代之的是Query接口,它們都用於執行HQL語句。Query和HQL是分不開的。
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();