管理Session
傳統方法
Hibernate每次操作db時,需建立session。
// session factory
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
// 操作db
Session session = sessionFactory.openSession();
session.beginTransaction();
session.saveOrUpdate(entity);
session.getTransaction().commit();
session.close();
但每次的操作流程都是[建session]->操作DB->[關session]
除了重複的code太多,也不優雅。若能整合Spring,則有HibernateDaoSupport或HibernateTemplate可以使用。但如果有些專案單純想使用Hibernate卻不想使用Srping呢?這時就要自行管理了。
Spring的HibernateTemplate
先看看使用Srping的HibernateTemplate如何實作。
public class MyDao extends HibernateDaoSupport {
public void save(User e) {
getHibernateTemplate().saveOrUpdate(e);
}
public List<User> queryXXX() {
return getHibernateTemplate().execute(new HibernateCallback<List<User>>() {
@SuppressWarnings("unchecked")
@Override
public List<User> doInHibernate(Session session) throws HibernateException, SQLException {
// do your work
}
});
}
}
說明:
- 使用
Spring
的HibernateDaoSupport
,只要呼叫getHibernateTemplate()
就可以直接操作db,而且也不必手動關閉session
。 - 比較複雜的操作也是使用
HibernateCallback.doInHibernate(Session)
介面完成。並不直接操作session
。
自己實作
使用HibernateSessionFactory
提供session,並用HibernateSessionManager
管理session。
public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
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;
}
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null && session.isOpen()) {
session.close();
}
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
public static Configuration getConfiguration() {
return configuration;
}
public static Statistics getStatistics() {
return sessionFactory.getStatistics();
}
public static long getSessionOpenCount() {
return sessionFactory.getStatistics().getSessionOpenCount();
}
}
public class HibernateSessionManager {
public interface HibernateCallback<T> {
public T doInHibernate(Session session);
}
public <E> E execTemplate(HibernateCallback<E> hc) {
E result = null;
Session s = getSession();
Transaction tx = null;
try {
tx = s.beginTransaction();
result = hc.doInHibernate(s); // equals to: s.saveOrUpdate(entity);
tx.commit();
} catch(Exception e) {
e.printStackTrace();
if(tx != null) tx.rollback();
} finally {
if(s != null) {
s.close();
s = null;
}
}
return result;
}
protected Session getSession() {
return HibernateSessionFactory.getSession();
}
}