一,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)对象。 |
void | cancelQuery() 终止执行当前查询。 |
void | clear() 完整的清除这个session。 |
Connection | close() 停止这个Session,通过中断JDBC连接并且清空(cleaning up)它。 |
Connection | connection() 获取这个Session的JDBC连接。 如果这个session使用了积极的collection释放策略(如CMT-容器控制事务的环境下),关闭这个调用的连接的职责应该由当前应用程序负责。 |
boolean | contains(Object object) 检查这个对象实例是否与当前的Session关联(即是否为Persistent状态)。 |
Criteria | createCriteria(Class persistentClass) 为给定的实体类或它的超类创建一个新的Criteria实例。 |
Criteria | createCriteria(Class persistentClass,String alias) 根据给定的实体类或者它的超类创建一个新的Criteria实例,并赋予它(实体类)一个别名。 |
Criteria | createCriteria(String entityName) 根据给定的实体的名称(name),创建一个新的Criteria实例。 |
Criteria | createCriteria(String entityName,String alias) 根据给定的实体的名称(name),创建一个新的Criteria实例,并赋予它(实体类)一个别名 |
Query | createFilter(Object collection,String queryString) 根据给定的collection和过滤字符串(查询条件)创建一个新的Query实例。 |
Query | createQuery(String queryString) 根据给定的HQL查询条件创建一个新的Query实例。 |
SQLQuery | createSQLQuery(String queryString) 根据给定的SQL查询条件创建一个新的SQLQuery实例。 |
void | delete(Object object) 从数据库中移除持久化(persistent)对象的实例。 |
void | delete(String entityName,Object object) 从数据库中移除持久化(persistent)对象的实例。 |
void | disableFilter(String filterName) 禁用当前session的名称过滤器。 |
Connection | disconnect() 断开Session与当前的JDBC连接。 |
Filter | enableFilter(String filterName) 打开当前session的名称过滤器。 |
void | evict(Object object) 将当前对象实例从session缓存中清除。 |
void | flush() 强制提交刷新(flush)Session。 |
Object | get(Class clazz,Serializable id) 根据给定标识和实体类返回持久化对象的实例,如果没有符合条件的持久化对象实例则返回null。 |
Object | get(Class clazz,Serializable id,LockMode lockMode) 根据给定标识和实体类返回持久化对象的实例,如果没有符合条件的持久化对象实例则返回null。 |
Object | get(String entityName,Serializable id) 返回与给定的实体命名和标识匹配的持久化实例,如果没有对应的持久化实例则返回null。 |
Object | get(String entityName,Serializable id,LockMode lockMode) 返回与给定的实体类和标识所匹配的持久化实例,如果没有对应的持久化实例则返回null。 |
CacheMode | getCacheMode() 得到当前的缓存模式。 |
LockMode | getCurrentLockMode(Object object) 检测给定对象当前的锁定级别。 |
Filter | getEnabledFilter(String filterName) 根据名称获取一个当前允许的过滤器(filter)。 |
EntityMode | getEntityMode() 获取这个session有效的实体模式。 |
String | getEntityName(Object object) 返回一个持久化对象的实体名称。 |
FlushMode | getFlushMode() 获得当前的刷新提交(flush)模式。 |
Serializable | getIdentifier(Object object) 获取给定的实体对象实例在Session的缓存中的标识,如果该实例是自由状态(Transient)的或者与其它Session关联则抛出一个异常。 |
Query | getNamedQuery(String queryName) 从映射文件中根据给定的查询的名称字符串获取一个Query(查询)实例。 |
Session | getSession(EntityMode entityMode) 根据给定的实体模式(Entity Mode)开始一个新的有效的Session。 |
SessionFactory | getSessionFactory() 获取创建这个session的SessionFactory实例。 |
SessionStatistics | getStatistics() 获取这个session的统计信息。 |
Transaction | getTransaction() 获取与这个session关联的Transaction(事务)实例。 instance associated with this session. |
boolean | isConnected() 检查当前Session是否处于连接状态。 |
boolean | isDirty() 当前Session是否包含需要与数据库同步的(数据状态)变化 ?如果我们刷新提交(flush)这个session是否会有SQL执行? |
boolean | isOpen() 检查当前Session是否仍然打开。 |
Object | load(Class theClass,Serializable id) 在符合条件的实例存在的情况下,根据给定的实体类和标识返回持久化状态的实例。 |
Object | load(Class theClass,Serializable id,LockMode lockMode) 在符合条件的实例存在的情况下,根据给定的实体类、标识及指定的锁定等级返回持久化状态的实例。 |
void | load(Object object,Serializable id) 将与给定的标示对应的持久化状态(值)复制到给定的自由状态(trasient)实例上。 |
Object | load(String entityName,Serializable id) 在符合条件的实例存在的情况下,根据给定的实体类和标识返回持久化状态的实例。 |
Object | load(String entityName,Serializable id,LockMode lockMode) 在符合条件的实例存在的情况下,根据给定的实体类、标识及指定的锁定等级返回持久化状态的实例。 |
void | lock(Object object,LockMode lockMode) 从给定的对象上获取指定的锁定级别。 |
void | lock(String entityName,Object object,LockMode lockMode) 从给定的对象上获取指定的锁定级别。 |
Object | merge(Object object) 将给定的对象的状态复制到具有相同标识的持久化对象上。 |
Object | merge(String entityName,Object object) 将给定的对象的状态复制到具有相同标识的持久化对象上。 |
void | persist(Object object) 将一个自由状态(transient)的实例持久化。 |
void | persist(String entityName,Object object) 将一个自由状态(transient)的实例持久化。 |
void | reconnect() 不推荐的。 手工的重新连接只应用于应用程序提供连接的情况,在这种情况下或许应该使用 reconnect(java.sql.Connection) 。 |
void | reconnect(Connection connection) 重新连接到给定的JDBC连接。 |
void | refresh(Object object) 从数据库中重新读取给定实例的状态。 |
void | refresh(Object object,LockMode lockMode) 根据指定的锁定模式(LockMode),从数据库中重新读取给定实例的状态。 |
void | replicate(Object object,ReplicationMode replicationMode) 使用当前的标识值持久化给定的游离状态(Transient)的实体。 |
void | replicate(String entityName,Object object,ReplicationMode replicationMode) 使用当前的标识值持久化给定的游离状态(Transient)的实体。 |
Serializable | save(Object object) 首先为给定的自由状态(Transient)的对象(根据配置)生成一个标识并赋值,然后将其持久化。 |
Serializable | save(String entityName,Object object) 首先为给定的自由状态(Transient)的对象(根据配置)生成一个标识并赋值,然后将其持久化。 |
void | saveOrUpdate(Object object) 根据给定的实例的标识属性的值(注:可以指定unsaved-value。一般默认null。)来决定执行 save() 或update()操作。 |
void | saveOrUpdate(String entityName,Object object) 根据给定的实例的标识属性的值(注:可以指定unsaved-value。一般默认null。)来决定执行 save() 或update()操作。 |
void | setCacheMode(CacheMode cacheMode) 设置刷新提交模式。 |
void | setFlushMode(FlushMode flushMode) 设置刷新提交模式。 |
void | setReadOnly(Object entity, boolean readOnly) 将一个未经更改的持久化对象设置为只读模式,或者将一个只读对象标记为可以修改的模式。 |
void | update(Object object) 根据给定的detached(游离状态)对象实例的标识更新对应的持久化实例。 |
void | update(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 对象的生命周期
- thread: Session 对象的生命周期与本地线程绑定
- jta*: Session 对象的生命周期与 JTA 事务绑定
- managed: 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 返回
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();
}
}
- 使用可滚动的结果集 org.hibernate.ScrollableResults, 该对象中实际上并不包含任何对象, 只包含用于在线定位记录的游标. 只有当程序遍历访问 ScrollableResults 对象的特定元素时, 它才会到数据库中加载相应的对象.
- org.hibernate.ScrollableResults 对象由 Query 的 scroll 方法返回
- 需要在 Hibernate 配置文件中设置 JDBC 单次批量处理的数目, 应保证每次向数据库发送的批量的 SQL 语句数目与 batch_size 属性一致
- 若对象采用 “identity” 标识符生成器, 则 Hibernate 无法在 JDBC 层进行批量插入操作
- 进行批量操作时, 建议关闭 Hibernate 的二级缓存