sessionfactory单例

Hibernate常用的核心接口包括:

Configuration、SessionFactory、Session、Transaction、Query、Criteria。

在完成session获取的过程中,主要涉及Configuration、SessionFactory、Session接口。

Configuration接口:负责配置并启动Hibernate,创建SessionFactory对象。在Hibernate的启动过程中,Configuration类的实例首先定位映射文档位置,读取配置,然后创建SessionFactory对象。

SessionFactory接口:负责初始化Hibernate,并负责创建Session对象。这里用到了工厂模式,但是SessionFactory并不是轻量级的,因为在一般情况下,一个项目通常只需要一个SessionFactory就足够了,当需要操作多个数据库时,可以定义多个SessionFactory。

Session接口:负责执行被持久化对象的CRUD操作,但是Session对象是非线程安全的。

ThreadLocal类用于在并发环境下避免竞争,简化编程的机制,它在并发环境下提供了一个逻辑上全局的访问点,来访问线程本地变量。ThreadLocal的功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立的改变自己的副本,而不会和其他线程的副本冲突。从线程的角度来看,就好像每一个线程完全拥有该变量。

  1. public class ThreadLocal {
  2. //HashMap存储ThreadLocal变量,并实现了线程安全
  3. private Map values = Collections.synchronizedMap( new HashMap());
  4. public Object get(){
  5. Thread curThread = Thread.currentThread();
  6. Object obj = values.get(curThread);
  7. if(obj== null&&!values.containsKey(curThread)){
  8. obj = initialValue();
  9. values.put(curThread, obj);
  10. }
  11. return obj;
  12. }
  13. public void set(Object newValue){
  14. values.put(Thread.currentThread(), newValue);
  15. }
  16. public Object initialValue(){
  17. return null;
  18. }
  19. }

SessionFactory在Hibernate中起到了一个缓冲区的作用,它缓冲了Hibernate自动生成的SQL语句和其他的映射数据,还缓冲了一些将来可能要重复利用的数据。首先介绍下Hibernate的传递配置属性的三种方式:

No.1 使用hibernate.cfg.xml:

  1. Configuration cfg = new Configuration();
  2. cfg.configure( "hibernate.cfg.xml");

No.2 使用hibernate.properties:

  1. Configuration cfg = new Configuration();
  2. cfg.configure( "/hibernate.properties");
  3. cfg.addResource( "com/demo/hibernate/beans/User.hbm.xml");
  4. Configuration cfg = new Configuration();
  5. cfg.configure( "/hibernate.properties");
  6. cfg.addClass(com.demo.hibernate.beans.User.class);

No.3 构造时硬编码:

  1. Configuration cfg = new Configuration()
  2. .addClass(com.demo.hibernate.beans.User.class)
  3. .setProperty( "hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
  4. .setProperty( "hibernate.connection", "java:com/env/jdbc.test");
  5. .setProperty( "hibernate.order_updates", "true");

我们知道Configuration实例是一个启动期间(sartup-time)的对象,一旦SessionFactory创建完成她就被丢弃。对于SessionFactory来说,它采用了工厂模式,用户程序从工厂类SessionFactory中取得Session的实例,它的设计者的意图是让她在整个应用中共享。典型地说,一个项目通常只需要一个SessionFactory就足够了。因此,我们可以这样定义SessionFactory类:

  1. import org.hibernate.HibernateException;
  2. import org.hibernate.Session;
  3. import org.hibernate.cfg.Configuration;
  4. public class HibernateSessionFactory {
  5. private static final Configuration cfg = new Configuration();
  6. private static org.hibernate.SessionFactory sessionFactory;
  7. private static final ThreadLocal threadLocal = new ThreadLocal();
  8. public static Session currentSession() throws HibernateException{
  9. Session session = (Session)threadLocal.get();
  10. if(session == null){
  11. if(sessionFactory == null){
  12. try{
  13. cfg.configure( "hibernate.cfg.xml");
  14. sessionFactory = cfg.buildSessionFactory();
  15. } catch(HibernateException e){
  16. System.out.println( "Error Creating SessionFacotry.");
  17. e.printStackTrace();
  18. }
  19. }
  20. session = sessionFactory.openSession();
  21. threadLocal.set(session);
  22. }
  23. return session;
  24. }
  25. public static void cloaseSession() throws HibernateException{
  26. Session session = (Session)threadLocal.get();
  27. threadLocal.set( null);
  28. if(session != null){
  29. session.close();
  30. }
  31. }
  32. }
总之,ThreadLocal让一次程序的运行来使用一个Session,而所有的Session都公用一个SessionFacotry,这样做有3个好处:

让所有用户共用一个SessionFactory,避免了重复创建SessionFactory而造成的资源浪费;

为每一个用户访问都创建一个Session,避免了不同用户之间的Session冲突;

在每一次程序运行的周期内,共用一个Session,既可以避免资源浪费,有提供了资源的共享,让一次运行的多个操作共用一个Session资源,为事务的操作也提供了基础。

因此,HibernateSessionFactory创建的实例关系图如下:

整个系统只有一个Configuration和SessionFactory对象,而不同的用户访问有不同的SessionA和SessionB。每一个Session在生命期内,都可以进行多个操作,直到线程访问结束




   转载于https://blog.csdn.net/u014753393/article/details/51255517

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值