hibernate一些小结(写给自己,以便以后记得)
-
所谓持久化就是把内存中的数据同步保存到数据库(如关系数据库)或永久存储设备(如硬盘、磁带等)中.
-
Hibernate Web应用的开发一般经过以下几个步骤。
(1)创建数据库。
(2)将Hibernate所需的JAR包复制到WEB-INF/lib下。
(3)创建Hibernate的配置文件。
(4)利用Hibernate的第三方工具或Eclipse的有关插件从数据库中创建出相应的实体对象及其ORM映射文件。
(5)创建Hibernate的SessionFactory类。
(6)通过SessionFactory创建Session实例。
(7)通过创建的Session实例进行持久化对象的管理。
(8)通过创建的Transaction实例进行事务管理。
(9)通过创建的Query或Criteria实例实现数据库的查询。
-
2.4.2 使用Hibernate操作数据库需要七个步骤
(1)读取并解析配置文件
Configuration conf = new Configuration().configure();
创建一个Configuration对象,并通过该对象的configure()方法加载Hibernate配置文件。
(2)读取并解析映射信息,创建SessionFactory
SessionFactory sf = conf.buildSessionFactory();
完成配置文件和映射文件的加载后,将得到一个包括所有Hibernate运行期参数的Configuration实例,通过Configuration实例的buildSessionFactory()方法可以构建一个唯一的SessionFactory,构建SessionFactory要放在静态代码块中,因为它只在该类被加载时执行一次。
(3)打开Session
Session session = sf.openSession();
一般的持久化方法(CRUD)都是通过Session来调用的。
Session是一个轻量级对象,通常将每个Session实例和一个数据库事务绑定,也就是每执行一个数据库事务,都应该先创建一个新的Session实例,在使用Session后,还需要关闭Session。
Session是非线程安全的。Session中包含了数据库操作相关的状态信息,如果多个线程同时使用一个Session实例进行CRUD(增删查改),就很有可能导致数据存取的混乱,在hibernate中threadlocal类解决这个问题,线程局部变量(ThreadLocal)其实的功用非常简单, 就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。
ThreadLocal类本身不代表线程要访问的变量,这个类的成员变量才是。JDK1.5给ThreadLocal加了泛型功能,即ThreadLocal的泛型T才是要线程的本地变量。线程通过ThreadLocal的get和set方法去访问这个变量T。
小知识:获得session实例有两种方法:getSession()和getCurrentSession(),它们的区别:
(1)通过SessionFactory的方法getCurrentSession()获取当前线程中的Session,当调用时,hibernate将session绑定到当前线程,事务结束后,hibernate将session从当前线程中释放,并且关闭 session。当再次调用getCurrentSession()时,将得到一个新的session,并重新开始这一系列工作。
(2)通过SessionFactory创建Session实例时,代码如下。
Session session=sessionFactory.openSession();
创建Session后,就可以通过创建的Session进行持久化操作了,在创建Session实例后,不论是否执行事务,最后都需要关闭Session实例,释放Session实例占用的资源。即关闭Session实例:session.close();
(3)getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭;
(4)getCurrentSession () 使用当前的session,openSession() 重新建立一个新的session
(5)getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行如下设置
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>当 SessionFactory 启动时,Hibernate 会根据配置创建相应的 CurrentSessionContext,在 getCurrentSession() 被调用的时候,实际被执行的方法是
CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空,currentSession 会调用 SessionFactory 的 openSession。因此, 对于 Java EE 来说,getCurrentSession()是更好地获取 Session 的方法。
(4)开始一个事务(增删改操作必须,查询操作可选)
Transaction tx = session.beginTransaction();
Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction或者JTA Transaction的封装,可通过hibernate.properties或者hibernate.cfg.xml中的配置JDBCTransaction或者是JTATransaction,默认情况下使用JDBCTransaction,如果你配置为: hibernate.transaction.factory_class =
net.sf.hibernate.transaction.JTATransactionFactory
将使用JTATransaction 。
(5)数据库操作
session.save(user);//或其它操作
(6)提交事务或者回滚事务
tx.commit(); 或者tx.rollback();
(7)关闭session
session.close();