如何理解Hibernate中的HibernateSessionFactory类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解Hibernate中的HibernateSessionFactory类相关的知识,希望对你有一定的参考价值。

package com.zz.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see @link http://hibernate.org/42.html .
*/
public class HibernateSessionFactory

/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static org.hibernate.SessionFactory sessionFactory;

private static Configuration configuration = new Configuration();
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static String configFile = CONFIG_FILE_LOCATION;

static
try
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
catch (Exception e)
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();


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;


/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory()
try
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
catch (Exception e)
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();



/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException
Session session = (Session) threadLocal.get();
threadLocal.set(null);

if (session != null)
session.close();



/**
* return session factory
*
*/
public static org.hibernate.SessionFactory getSessionFactory()
return sessionFactory;


/**
* return session factory
*
* session factory will be rebuilded in the next call
*/
public static void setConfigFile(String configFile)
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;

/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration()
return configuration;




HibernateSessionFactory类是自定义的SessionFactory,名字可以根据自己的喜好来决定。这里用的是HibernateSessionFactory,其内容及解释。上述代码是由myeclipse 自动生成的;也可以根据自己的情况写出:

package com.zz.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

//在使用hibernate开发项目,请一定保证只有一个SessionFactory
//一个数据库对应一个SessionFactory 对象.
final public class MySessionFactory

private static SessionFactory sessionFactory=null;

private MySessionFactory()



static

sessionFactory =new Configuration().configure("com/zz/config/hsp.cfg.xml").buildSessionFactory();
System.out.println("sessionFactory 类型"+sessionFactory);


public static SessionFactory getSessionFactory()
return sessionFactory;




在Hibernate中,Session负责完成对象持久化操作。该文件负责创建Session对象,以及关闭Session对象。从该文件可以看出,Session对象的创建大致需要以下3个步骤:

① 初始化Hibernate配置管理类Configuration。

② 通过Configuration类实例创建Session的工厂类SessionFactory。

③ 通过SessionFactory得到Session实例。
?1. Configuration接口

Configuration负责管理Hibernate的配置信息。Hibernate运行时需要一些底层实现的基本信息。这些信息包括:数据库URL、数据库用户名、数据库用户密码、数据库JDBC驱动类、数据库dialect。用于对特定数据库提供支持,其中包含了针对特定数据库特性的实现,如Hibernate数据库类型到特定数据库数据类型的映射等。

使用Hibernate必须首先提供这些基础信息以完成初始化工作,为后续操作做好准备。这些属性在Hibernate配置文件hibernate.cfg.xml中加以设定,当调用:

Configuration config=new Configuration().configure();

时,Hibernate会自动在目录下搜索hibernate.cfg.xml文件,并将其读取到内存中作为后续操作的基础配置。
? 2. SessionFactory接口

SessionFactory负责创建Session实例,可以通过Configuration实例构建SessionFactory。

Configuration config=new Configuration().configure();

SessionFactorysessionFactory=config.buildSessionFactory();

Configuration实例config会根据当前的数据库配置信息,构造SessionFacory实例并返回。SessionFactory一旦构造完毕,即被赋予特定的配置信息。也就是说,之后config的任何变更将不会影响到已经创建的SessionFactory实例sessionFactory。如果需要使用基于变更后的config实例的SessionFactory,需要从config重新构建一个SessionFactory实例。

SessionFactory保存了对应当前数据库配置的所有映射关系,同时也负责维护当前的二级数据缓存和Statement Pool。由此可见,SessionFactory的创建过程非常复杂、代价高昂。这也意味着,在系统设计中充分考虑到SessionFactory的重用策略。由于SessionFactory采用了线程安全的设计,可由多个线程并发调用。
?3. Session接口

Session是Hibernate持久化操作的基础,提供了众多持久化方法,如save、update、delete等。通过这些方法,透明地完成对象的增加、删除、修改、查找等操作。

同时,值得注意的是,HibernateSession的设计是非线程安全的,即一个Session实例同时只可由一个线程使用。同一个Session实例的多线程并发调用将导致难以预知的错误。

Session实例由SessionFactory构建:

Configuration config=new Configuration().configure();

SessionFactorysessionFactory=config.buldSessionFactory();

Session session=sessionFactory.openSession();
?4. Transaction接口

Transaction是Hibernate中进行事务操作的接口,Transaction接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA中的UserTransaction,甚至可以是CORBA事务。之所以这样设计是可以让开发者能够使用一个统一的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移值。事务对象通过Session创建。例如以下语句:

Transaction ts=session.beginTransaction();
?5. Query接口

在Hibernate 2.x中,find()方法用于执行HQL语句。Hibernate 3.x废除了find()方法,取而代之的是Query接口,它们都用于执行HQL语句。Query和HQL是分不开的。

Query query=session.createQuery(“fromtable where id=1”);

例如以下语句:

Query query=session.createQuery("fromtable whereid=?");

就要在后面设置其值:

Query.setString(0,"要设置的值");

上面的方法是通过“?”来设置参数,还可以用“:”后跟变量的方法来设置参数,如上例可以改为:

Query query=session.createQuery("fromtable whereid=:1");

Query.setString("kchValue","要设置的课程号值");

其使用方法是相同的,例如:

Query.setParameter(0,"要设置的值");

Query还有一个list()方法,用于取得一个List集合的示例,此示例中包括可能是一个Object集合,也可能是Object数组集合。例如:

Query query=session.createQueryhttp://www.315nk.com/xtkf/?fromtable whereid=1");

List list=query.list();
参考技术A jsp里的session是http范畴的概念,因为http是无状态的协议,所以需要一个由服务端维护的用户储存用户状态的东西。
hibernate的session是一个数据连接的对象,你可以理解成一个数据库连接。如果jsp页面需要获取hibernate的session,可以调用SessionFactory.getCurrentSession()来获得(当然还需要其他一些配置)。不过一般不在jsp里直接对hibernate的session进行操作。

Hibernate-事务理解

一.数据库事务的概念

  数据库事务是指由一个或者多个SQL语句组成的工作单元.这个工作单元中的SQL语句相互依赖,如果有一个Sql语句执行失败就必须撤销整个工作单元.

  在并发环境中,多个事务同时访问相同的数据资源时,可能会造成各种并发问题,可通过设定数据库的事务隔离级别来避免,还可用悲观锁和乐观锁来解决丢失更新这一并发问题.

二.数据库事务必须具备ACID特征

  Atomic 原子性:  整个事务不可分割,要么都成功,要么都撤销.

  Consistency一致性;  事务不能破坏关系数据的完整性和业务逻辑的一致性,例如:转账,应保证事务结束后两个账户的存款总额不变.

  Isolation 隔离性:  多个事务同时操纵相同的数据时,每个事务都有各自的完整数据空间.

  Durabiity持久性:  只要事务成功结束,对数据库的更新就必须永久保存下来,即使系统发生崩溃,重启数据库后,数据库还能恢复到事务成功结束是的状态.

三.事务的边界声明

 只要声明了一个事务,数据库系统就会自动保证事务的ACID特性

  声明事务的包含:

    事务的开始边界:

      事务的正常结束边界(commit):提交事务,永久保存

      事务的异常结束边界(rollback) :撤销事务,数据库回退到执行事务前的状态.

以上是关于如何理解Hibernate中的HibernateSessionFactory类的主要内容,如果未能解决你的问题,请参考以下文章

与 SQL 相比,Hibernate JPQL 查询非常慢

如何理解Hibernate中的HibernateSessionFactory类

使用 Vaadin Hibernates ThreadLocal<Session>.get() 在第一次调用后返回 null

休眠:分离没有级联到集合

谈谈你对Hibernate的理解

Hibernate