在Hibernate 中,我们知道
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
session = sessionFactory.openSession();
这三个操作耗费的时间和资源是很多的,特别是对于 Configuration 和 SessionFactory ,在整个项目的运行中,一般我们只实例化它们一次,后续要用到的话直接调用已有的对象即可,所以我们采用单例模式去写。
HibernateUtil.java
public class HibernateUtil {
private static SessionFactory sessionFactory ;
static{
try {
Configuration config = new Configuration().configure();
sessionFactory = config.buildSessionFactory();
} catch (HibernateException e) {
e.printStackTrace();
}
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
public static Session getSession(){
return sessionFactory.openSession();
}
}
这里结合多种措施实现单例:
1. 采用 private static 来修饰 SessionFactory 的对象 sessionFactory ,private 使得只有本类才能对它访问和操作,static 使得它可以被下面的静态方法调用。
2. 使用 static {...} 静态块,并在其中实例化 SessionFactory。静态代码块在整个项目启动的时候就执行一次,执行顺序甚至先于HibernateUtil 的构造方法,并且执行一次之后,以后不再执行。这样使得 Configuration 只读取一次默认配置文件,SessionFactory 只实例化一次。
3. try catch 环绕static {...}静态块,保证静态块内的语句正常执行。
4. 采用public static 修饰 getSessionFactory() ,实现对唯一对象 sessionFactory 的隐蔽,用户只能通过访问HibernateUtil.getSessionFactory() 来得到 sessionFactory,既安全又方便。
5. 采用public static 修饰 getSession(),用户通过 HibernateUtil.getSession() 来得到不同的 Session 对象,非常的方便,代码也显得优雅。
已亲测:
SessionFactory sf1 = HibernateUtil.getSessionFactory();
SessionFactory sf2 = HibernateUtil.getSessionFactory();
System.out.println(sf1==sf2);
Session s1 = HibernateUtil.getSession();
Session s2 = HibernateUtil.getSession();
System.out.println(s1==s2);
打印值是
true false
注意事项:
1. 这个类里没有 closeSessionFactory() 。
SessionFactory 实际上不需要关闭,因为我们项目在运行的时候经常需要它来创造 Session 对象,而当我们不需要创造 Session 对象的时候,这个项目多半也关闭不再运行了,SessionFactory 随着项目的关闭而关闭,总之不需要我们手动去关闭。
2. 这个类里面没有 closeSession() 。
这个设计是希望使用者在外部类需要 Session 的时候,通过这种方式获取和关闭
Session session = HibernateUtil.getSession();
...
session.close();
从性能方面来说,session.close() 和 HibernateUtil.closeSession() 是一样的;而从代码字数来说,session.close() 完胜。
End .