在第8章的两个例子中,已经涉及到了Hibernate API的知识,通过Hibernate的API实现数据库表的增删改查操作。Hibernate中有几个常用的概念:SessionFactory、Session与Trasaction。注意这里的Session不同于Servlet中的HttpSession,二者虽然都可理解为会话,但使用的过程是不一样的。这一章将对Hibernate API做一个简单归类总结。
9.1 Configuration类
Configuration类负责管理Hibernate的配置信息,一个Configuration类的实例代表了有用程序中Java类导数据库的映射的集合。应用程序通常只是创建一个Configuration实例,并通过它来创建SessionFactory实例,例如下面的代码:
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Configuration是Hibernate的入口,在新建一个Configuration的实例时,Hibernate会在类路径中查找hibernate.properties文件和hibernate.cfg.xml文件,如果这两个文件都存在,则hibernate.cfg.xml文件将会覆盖hibernate.properties文件;如果两个文件都不存在,则抛出异常。
Configuration提供了带参数的访问方法,用户可以指定配置文件的路径,而不用系统默认的hibernate.cfg.xml文件,示例代码如下:
String fileName = “use_hibernate_cfg.xml”;
Configuration configuration = new Configuration().configure(fileName);
9.2 SessionFactory接口
SessionFactory (org.hibernate.SessionFactory)是一个线程安全的Session工厂类,能为不同的线程生成不同的Session。SessionFactory维护着Session相关的资源,包括数据库连接池等、缓存数据等。
9.2.1 SessionFactory简介
SessionFactory接口是Hibernate的核心接口之一,SessionFactroy接口负责初始化Hibernate,在初始化Hibernate的时候会创建一个Configuration类的实例,该实例加载Hibernate的配置文件,并将已经写好的映射文件交给它处理,它充当数据存储源的代理,并负责创建Session对象。SessionFactory接口用到了工厂模式。需要注意的是:一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,需要为每个数据库指定一个SessionFactory。
9.2.2 SessionFactory使用
当使用SessionFactory创建成功以后,Configuration类的实例就没有用了,可以把Configuration类的实例抛弃掉,代码如下:
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
SessionFactory一旦声明,就不必去估计数据库连接的问题,这样对开发者来说很方便。下面的代码是SessionFactory中的一个修改方法。
public int updateDemo(String str){
int results=0;
SessionFactory sessionFactory =this.getSessionFactory();
Session session=(Session)this.getSessionFactory().getCurrentSession();
sessionFactory.openSession();
Transaction transaction =session.beginTransaction();
Query query =session.createQuery(str);
results =query.executeUpdate();// query.executeUpdate()方法返回的整型值
return results;
}
此方法如果传入一条数据修改语句。就可以直接执行返回成功与否的结果。而此处的SessionFactory一旦声明,就不必去估计数据库连接的问题,很方便。
9.3 Seesion接口
Session是Hibernate运作的核心,对象的生命周期、事务的管理以及数据库的存取都和它有密切相关,有效的管理Session是使用Hibernate的重点。
9.3.1 Hibernate中Session的概念
在各种Session 管理方案中, ThreadLocal 模式得到了大量使用。ThreadLocal 是Java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
9.3.2 Hibernate中Session的使用
Session是SessionFactory创建的。由于SessionFactory是线性安全的,可以让多个线程同时存取SessionFactory而不会引起数据共享的问题。Session是非线性安全的,让多个线程共享一个Session,会引起线程冲突或者线程混乱。
使用ThreadLocal变量,可以解决Session的管理问题。使用ThreadLocal可以有效的隔离线程执行所使用的数据,这样可以解决多个线程共享数据的问题,在Hibernate中使用HibernateSessionFactory来管理Session,HibernateSessionFactory类的代码如下(这里省略了import的内容):
package com.cn.factory;
public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal threadLocal = new ThreadLocal();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
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() {
}
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;
}
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
public static Configuration getConfiguration() {
return configuration;
}
}
通过这个类,可以很方便的管理Session,避免了多线程冲突或者多线程混乱的问题。在一个应用程序中,如果只连接一个数据库,则指需要一个HibernateSessionFactory类。
9.4 Trasaction接口
Transaction代表一次事务,事务内包含若干的数据修改,事务提交后才生效。如果事务失败或者回滚,所有的修改都会失效。Hibernate的事务不同于数据库的事务。Hibernate可能使用各种机制保证事务性,包括JTA(Java Transaction API,Java事务接口)、第三方事务管理、数据库事务等。
9.4.1 Trasaction接口简介
Transaction接口是org.hibernate.Transaction接口,它是封装底层事物的接口,底层的事务包括JDBC API、JTA和CORBA(Common Object Request Broker Architecture) API。
9.4.2 Trasaction接口的使用
在使用Hibernate操作数据库时,通过Trasaction来开启事务,提交事务和关闭事务。如果事务部开启,则无法操作数据库数据。Trasaction的用法如下:
public void modifyUsers(Object object) {
// 修改数据的方法
Session session = HibernateSessionFactory.getSession();
try {
session.beginTransaction();
// 开启事务
session.update(object);
// 修改数据
session.getTransaction().commit();
// 提交事务
} catch (Exception e) {
session.getTransaction().rollback();// 回滚事务
} finally {
session.close();
// 关闭session
}
}
9.5 Hibernate配置参数介绍
在第8章中的两个例子中都使用了Hibernate的配置,这一节重点对Hibernate的配置参数做介绍。Hibernate是个很有弹性的框架,能支持各种数据库、各种情景下的数据库操作,因此Hibernate有很大的配置参数。一般情况下,Hibernate默认的配置能够胜任绝大多数的工作。如果不满足,只需在Hibernate配置文件中覆盖默认的参数即可。
9.5.1 配置文件参数
Hibernate配置文件可以为xml文件或者properties文件。默认的配置文件名称为hibernate.cfg.xml与hibernate.properties,位于classpath下面。
参数即可以配置在cfg.xml文件中,也可以配置在properties文件中。在properties文件中时,参数是具有hibernate前缀的,而cfg.xml文件中没有,例如在hibernate.properties中的配置如下:
hibernate.connection.driver_class = com.mysql.jdbc.Driver
hibernate.connection.url = jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8
hibernate.connection.username = root
hibernate.connection.passwordd = admin
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.hbm2ddl.auto = create
hibernate.current_session_context_class = thread
hibernate.properties中配置了参数,hibernate.cfg.xml中就不用重复配置相同的内容了,可以只声明实体类映射文件的位置,hibernate.cfg.xml的配置如下:
|