由于SessionFactory是一个重量级的类,在一个应用中我们需要做成单例的,我选择的做法是: `
1 import org.hibernate.SessionFactory; 2 import org.hibernate.cfg.Configuration; 3 final public class Utils { 4 5 private static SessionFactory sessionFactory=null; 6 static{ 7 //创建SessionFactory会话工厂 8 sessionFactory=new Configuration().configure().buildSessionFactory(); 9 } 10 private Utils(){ 11 } 12 13 public static SessionFactory geSessionFactory(){ 14 return sessionFactory; 15 } 16 } 17 `
这样就可以在需要的地方直接调用
1 SessionFactory factory=Utils.geSessionFactory(); 2 3 Session s1=factory.openSession(); 4 Session s3=factory.getCurrentSession();
openSession()是打开一个Session,因此每次得到的Session都不一样
getCurrentSession()是得到当前线程的一个Session,在一个thread中使用该方法得到的Session都是同一个Session 但是在使用getCurrentSession()前需要在hibernate.cfg.xml中做如下配置:
1 <!-- java程序 --> 2 <property name="current_session_context_class">thread</property> 3 <!-- web程序 --> 4 <property name="current_session_context_class">jta</property>
否则会报如下错误: No CurrentSessionContext configured!
在使用getCurrentSession()得到的session做查询操作(load())时需要使用事务,否则 会报如下错误:
Exception in thread "main" org.hibernate.HibernateException: load is not valid without active transaction
而且这个session是自动关闭的
1 使用load()查询时,如果查询不到,则会返回null, load()使用一种代理机制,如果不使用查询得到的对象,则不会执行SQL语句,只有使用对象时才会执行SQL语句 【懒加载】 2 3 get()查询,如果查询不到,则会抛出异常,且在查询时就执行SQL语句,不管查询的结果会不会使用