Hibernate(三):Hibernate核心类,接口

本文深入讲解Hibernate框架中的Configuration、SessionFactory和Session三个核心组件的功能与使用方法。Configuration负责配置信息管理,SessionFactory作为数据存储源的代理,Session则是进行数据库操作的主要接口。

一,Configuration

      Configuration是 一个接口,作用是对它进行启动,以及负责管理Configuration的配置信息,包括以下内容:

  • Hibernate运行的底层信息:数据库的URL,用户名,密码,JDBC驱动,数据库的Dialect,数据库连接池(对应hibernate.cfg,xml)
  • 持久化类与数据表的映射关系(*.hbm.xml)

      在Hibernate启动的过程中Configuration的实例首先先定义映射文档的文职,读取这些配置,然后创建一个SessionFactory对象。

       一个org.hibernate.cfg.Configuration实例代表了一个应用程序中Java类型到SQL数据库映射的完整集合。Configuration被用来构建一个不可变的SessionFactory,映射定义则由不同的XML映射定义文件编译而来。

1.为Configuration指定映射文件

     可以直接实例化Configuration来获取一个实例,并为它指定XML映射文件,如果映射文件在类路径中,请使用addResource()

Configuration cfg = new Configuration().addResource("类路径");

2.为Configuration指定持久化类

     指定被映射的类, 让Hibernate去寻找映射定义文件

Configuration cfg=new Configuration().addClass(com.hibernate.beans.User.class);

Hibernate会在类路径中寻找名字为/com/ibernate/beans/User.hbml.xml映射定义文件

3,为Configuration指定配置属性

Configuration cfg =new Configuration().addClass(com.demo.hibernate.beans.User.class)
.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource","java:comp/env/jdbc/test")
.setProperty("hibernate.order_update","true");
4.Configuration的加载方式 
    在Hibernate的启动与开发中,需要使用一个Configuration,需要为它设置三个内容:数据库连接属性,hbm,xml,POJO类(第二个和第三个只需设置一个,就会自动寻找另一个)

  (1)使用hibernate.cfg.xml。该文件设置了数据库连接属性和hbm.xml映射文件配置。Hibernate会自动加载该配置属性。

Configuration cfg = new Configuration();
cfg.configuration("hibernate.cfg.xml");

  (2)使用hibernate.properties

Configuration cfg = new Configuration();

  (3)在完全构造时进行硬编码构造:

Configuration cfg =new Configuration()
.addClass(com.demo.hibernate.beans.User.class)
.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource","java:comp/env/jdbc/test")
.setProperty("hibernate.order_update","true");

二,SessionFactory

     SessionFactory接口负责初始化Hibernate,充当数据存储源的代理。起到一个缓冲区的作用,缓冲了Hibernate自动生成的 SQL语句和其他映射数据,缓冲了一些将来有可能重复利用的数据。

1.特点:

      针对单个数据库映射关系经过编译后的内存镜像,是线程安全的

      SessionFactory对象一旦构造完成,即被赋予特定的配置信息(一旦SessionFactory构造完成,配置文件变更不再影响对象)

     构造SessionFactory很浪费资源,一般情况下只初始化一个SessionFactory对象。

    如果操作多个数据库,必须为每个数据库指定一个SessionFactory

2.创建SessionFactory对象:

    (1)实例化Configuration对象,默认读取src目录下的hibernate.cfg.xml配置文件

Configuration cfg = new Configuration();
cfg.configuration("hibernate.cfg.xml");
      (2)通过Configuration的buildSessionFactory()方法构建唯一的SessionFactory
SessionFactory sessionFactory = config.buildSessionFactory

Hibernate4 新增了一个 ServiceRegistry 接口,所有基于 Hibernate 的配置或者服务都必须统一向这个 ServiceRegistry  注册后才能生效
Hibernate4 中创建 SessionFactory 的步骤


三,Session

     Session接口是Hibernate向应用程序提供操作数据库的主要接口,它是抽象了持久化服务概念的核心抽象API类,提供了基本的保存,更新,删除和加载Java对象的方法。

特点:

           (1)  是应用程序与数据库之间交互操作的一个单线程对象,是Hibernate的运作中心

             (2)所有持久化对象必须在Session的管理下才可以进行持久化操作

             (3)单线程,生命周期短,代表了一次会话过程

              (4)每一个Session实例与一个数据库事务绑定:每执行一个数据库事务操作,就先创建一个Session实例,如果事务执行出现异常,撤销事务。无论成功与否,都要调用Session的close()方法,释放实例占用的资源

              (5)对象的实例状态就是之前提到过的三种:临时状态(自由),持久化状态,游离状态。

               (6)Session提供的方法使对象的状态在这三种状态中来回的变换:

  • 自由状态的实例可以通过调用 save(),persist()或者saveOrUpdate() 方法进行持久化。
  •  持久化实例可以通过调用delete()变成游离状态。
  • 通过get()或load()方法得到的实例都是持久化状态的。
  •  游离状态的实例可以通过调用 update(),saveUpdate(),lock()或者replicate() 进行持久化。
  • 游离或者自由状态下的实例可以通过调用merge()方法成为一个新的持久化实例。

Session接口中的方法如下:

Method Summary
 Transaction       beginTransaction()
          开始一个工作单元并且返回相关联的事务(Transaction)对象。
 voidcancelQuery()
          终止执行当前查询。
 voidclear()
          完整的清除这个session。
 Connectionclose()
          停止这个Session,通过中断JDBC连接并且清空(cleaning up)它。
 Connectionconnection()
          获取这个Session的JDBC连接。

如果这个session使用了积极的collection释放策略(如CMT-容器控制事务的环境下),关闭这个调用的连接的职责应该由当前应用程序负责。
 booleancontains(Object object)
          检查这个对象实例是否与当前的Session关联(即是否为Persistent状态)。
 CriteriacreateCriteria(Class persistentClass)
          为给定的实体类或它的超类创建一个新的Criteria实例。
 CriteriacreateCriteria(Class persistentClass,String alias)
          根据给定的实体类或者它的超类创建一个新的Criteria实例,并赋予它(实体类)一个别名。
 CriteriacreateCriteria(String entityName)
          根据给定的实体的名称(name),创建一个新的Criteria实例。
 CriteriacreateCriteria(String entityName,String alias)
          根据给定的实体的名称(name),创建一个新的Criteria实例,并赋予它(实体类)一个别名
 QuerycreateFilter(Object collection,String queryString)
          根据给定的collection和过滤字符串(查询条件)创建一个新的Query实例。
 QuerycreateQuery(String queryString)
          根据给定的HQL查询条件创建一个新的Query实例。
 SQLQuerycreateSQLQuery(String queryString)
          根据给定的SQL查询条件创建一个新的SQLQuery实例。
 voiddelete(Object object)
          从数据库中移除持久化(persistent)对象的实例。
 voiddelete(String entityName,Object object)
          从数据库中移除持久化(persistent)对象的实例。
 voiddisableFilter(String filterName)
          禁用当前session的名称过滤器。
 Connectiondisconnect()
          断开Session与当前的JDBC连接。
 FilterenableFilter(String filterName)
          打开当前session的名称过滤器。
 voidevict(Object object)
          将当前对象实例从session缓存中清除。
 voidflush()
          强制提交刷新(flush)Session
 Objectget(Class clazz,Serializable id)
          根据给定标识和实体类返回持久化对象的实例,如果没有符合条件的持久化对象实例则返回null。
 Objectget(Class clazz,Serializable id,LockMode lockMode)
          根据给定标识和实体类返回持久化对象的实例,如果没有符合条件的持久化对象实例则返回null。
 Objectget(String entityName,Serializable id)
          返回与给定的实体命名和标识匹配的持久化实例,如果没有对应的持久化实例则返回null。
 Objectget(String entityName,Serializable id,LockMode lockMode)
          返回与给定的实体类和标识所匹配的持久化实例,如果没有对应的持久化实例则返回null。
 CacheModegetCacheMode()
          得到当前的缓存模式。
 LockModegetCurrentLockMode(Object object)
          检测给定对象当前的锁定级别。
 FiltergetEnabledFilter(String filterName)
          根据名称获取一个当前允许的过滤器(filter)。
 EntityModegetEntityMode()
          获取这个session有效的实体模式。
 StringgetEntityName(Object object)
          返回一个持久化对象的实体名称。
 FlushModegetFlushMode()
          获得当前的刷新提交(flush)模式。
 SerializablegetIdentifier(Object object)
          获取给定的实体对象实例在Session的缓存中的标识,如果该实例是自由状态(Transient)的或者与其它Session关联则抛出一个异常。
 QuerygetNamedQuery(String queryName)
          从映射文件中根据给定的查询的名称字符串获取一个Query(查询)实例。
 SessiongetSession(EntityMode entityMode)
          根据给定的实体模式(Entity Mode)开始一个新的有效的Session。
 SessionFactorygetSessionFactory()
          获取创建这个session的SessionFactory实例。
 SessionStatisticsgetStatistics()
          获取这个session的统计信息。
 TransactiongetTransaction()
          获取与这个session关联的Transaction(事务)实例。 instance associated with this session.
 booleanisConnected()
          检查当前Session是否处于连接状态。
 booleanisDirty()
          当前Session是否包含需要与数据库同步的(数据状态)变化 ?如果我们刷新提交(flush)这个session是否会有SQL执行?
 booleanisOpen()
          检查当前Session是否仍然打开。
 Objectload(Class theClass,Serializable id)
          在符合条件的实例存在的情况下,根据给定的实体类和标识返回持久化状态的实例。
 Objectload(Class theClass,Serializable id,LockMode lockMode)
          在符合条件的实例存在的情况下,根据给定的实体类、标识及指定的锁定等级返回持久化状态的实例。
 voidload(Object object,Serializable id)
          将与给定的标示对应的持久化状态(值)复制到给定的自由状态(trasient)实例上。
 Objectload(String entityName,Serializable id)
          在符合条件的实例存在的情况下,根据给定的实体类和标识返回持久化状态的实例。
 Objectload(String entityName,Serializable id,LockMode lockMode)
          在符合条件的实例存在的情况下,根据给定的实体类、标识及指定的锁定等级返回持久化状态的实例。
 voidlock(Object object,LockMode lockMode)
          从给定的对象上获取指定的锁定级别。
 voidlock(String entityName,Object object,LockMode lockMode)
          从给定的对象上获取指定的锁定级别。
 Objectmerge(Object object)
          将给定的对象的状态复制到具有相同标识的持久化对象上。
 Objectmerge(String entityName,Object object)
          将给定的对象的状态复制到具有相同标识的持久化对象上。
 voidpersist(Object object)
          将一个自由状态(transient)的实例持久化。
 voidpersist(String entityName,Object object)
          将一个自由状态(transient)的实例持久化。
 voidreconnect()
          不推荐的。 手工的重新连接只应用于应用程序提供连接的情况,在这种情况下或许应该使用reconnect(java.sql.Connection)
 voidreconnect(Connection connection)
          重新连接到给定的JDBC连接。
 voidrefresh(Object object)
          从数据库中重新读取给定实例的状态。
 voidrefresh(Object object,LockMode lockMode)
          根据指定的锁定模式(LockMode),从数据库中重新读取给定实例的状态。
 voidreplicate(Object object,ReplicationMode replicationMode)
          使用当前的标识值持久化给定的游离状态(Transient)的实体。
 voidreplicate(String entityName,Object object,ReplicationMode replicationMode)
          使用当前的标识值持久化给定的游离状态(Transient)的实体。
 Serializablesave(Object object)
          首先为给定的自由状态(Transient)的对象(根据配置)生成一个标识并赋值,然后将其持久化。
 Serializablesave(String entityName,Object object)
          首先为给定的自由状态(Transient)的对象(根据配置)生成一个标识并赋值,然后将其持久化。
 voidsaveOrUpdate(Object object)
          根据给定的实例的标识属性的值(注:可以指定unsaved-value。一般默认null。)来决定执行 save()update()操作。
 voidsaveOrUpdate(String entityName,Object object)
          根据给定的实例的标识属性的值(注:可以指定unsaved-value。一般默认null。)来决定执行 save()update()操作。
 voidsetCacheMode(CacheMode cacheMode)
          设置刷新提交模式。
 voidsetFlushMode(FlushMode flushMode)
          设置刷新提交模式。
 voidsetReadOnly(Object entity, boolean readOnly)
          将一个未经更改的持久化对象设置为只读模式,或者将一个只读对象标记为可以修改的模式。
 voidupdate(Object object)
          根据给定的detached(游离状态)对象实例的标识更新对应的持久化实例。
 voidupdate(String entityName,Object object)
          根据给定的detached(游离状态)对象实例的标识更新对应的持久化实例。

(7)获得Session对象:

  • 获得SessionFactory对象(上面已讲过用法)
  • 根据SessionFactory实例对象获取Session

Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
....
tx.commit();
session.close();

(8)管理Session

   Hibernate  自身提供了三种管理 Session 对象的方法

  • Session 对象的生命周期与本地线程绑定
  • Session 对象的生命周期与 JTA 事务绑定
  • Hibernate 委托程序管理 Session 对象的生命周期
  在 Hibernate 的配置文件中, hibernate.current_session_context_class 属性用于指定 Session 管理方式, 可选值包括
  • thread: Session 对象的生命周期与本地线程绑定
  • jta*: Session 对象的生命周期与 JTA 事务绑定
  • managed: Hibernate 委托程序来管理 Session 对象的生命周期
 如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session。Hibernate 按一下规则把 Session 与本地线程绑定
  • 当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回 
  • 当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象
  • 当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动flush sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象
  • 若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadA 绑定, 并将 sessionB 返回 
(9)Session批量处理数据
Session 的 save() 及 update() 方法都会把处理的对象存放在自己的缓存中. 如果通过一个 Session 对象来处理大量持久化对象, 应该及时从缓存中清空已经处理完毕并且不会再访问的对象. 具体的做法是在处理完一个对象或小批量对象后, 立即调用 flush() 方法刷新缓存, 然后在调用 clear() 方法清空缓存
代码示例:
News news=null;
for(int i=0;i<10000;i++){
         news=new News();
         news.setTitle("--"+i);
         session.save(news);
         if((i+1)%20==0){
               session.flush();
               session.clear();
              }
     }
批量更新: 在进行批量更新时, 如果一下子把所有对象都加载到 Session 缓存, 然后再缓存中一一更新, 显然是不可取的
  • 使用可滚动的结果集 org.hibernate.ScrollableResults, 该对象中实际上并不包含任何对象, 只包含用于在线定位记录的游标. 只有当程序遍历访问 ScrollableResults 对象的特定元素时, 它才会到数据库中加载相应的对象. 
  • org.hibernate.ScrollableResults 对象由 Query 的 scroll 方法返回
代码示例:

通过 Session 来进行处理操作会受到以下约束
  • 需要在  Hibernate 配置文件中设置 JDBC 单次批量处理的数目, 应保证每次向数据库发送的批量的 SQL 语句数目与 batch_size 属性一致
  • 若对象采用 “identity” 标识符生成器, 则 Hibernate 无法在 JDBC 层进行批量插入操作
  • 进行批量操作时, 建议关闭 Hibernate 的二级缓存



                


    





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值