通常我们使用hibernate总会写一个HibernateUtil类,大体这样:
public class HibernateUtil { public static final SessionFactory sessionFactory; static { try { //采用默认的hibernate.cfg.xml来启动一个Configuration的实例 Configuration configuration = new Configuration() .configure(); //由Configuration的实例来创建一个SessionFactory实例 sessionFactory = configuration.buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } //ThreadLocal可以隔离多个线程的数据共享,因此不再需要对线程同步 public static final ThreadLocal<Session> session = new ThreadLocal<Session>(); public static Session currentSession() throws HibernateException { Session s = session.get(); //如果该线程还没有Session,则创建一个新的Session if (s == null) { s = sessionFactory.openSession(); //将获得的Session变量存储在ThreadLocal变量session里 session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = session.get(); if (s != null) s.close(); session.set(null); } }
将session绑定在当前线程内.
在hibernate3中增加了SessionFactory.getCurrentSession()直接获取上下文相关session。通过hibernate.current_sessiong根据事物环境来指定上下文session的底层实现
像这样:(hibernate.cfg.xml中<session-factory>子元素)
<!--指定根据当前线程来界定上下文相关Session--> <property name="hibernate.current_session_context_class">thread</property>
<!--指定根据JTA事物来界定上下文session--> <property name="hibernate.current_session_context_class">jta</property>
public class NewsManager { public static void main(String[] args) throws Exception { //实例化Configuration,这行代码默认加载hibernate.cfg.xml文件 Configuration conf = new Configuration().configure(); //以Configuration创建SessionFactory SessionFactory sf = conf.buildSessionFactory(); //打开上下文相关的Session Session sess = sf.getCurrentSession(); //开始事务 Transaction tx = sess.beginTransaction(); //创建消息实例 News n = new News(); //设置消息标题和消息内容 n.setTitle("疯狂Java联盟成立了"); n.setContent("疯狂Java联盟成立了," + "网站地址http://www.crazyit.org"); //保存消息 sess.save(n); //提交事务 tx.commit(); //Session随事务的提交自动关闭,因此无需手动关闭 } }