Hibernate配置文件详解

Hibernate的JNDI名称绑定是在net.sf.hibernate.impl.SessionFactoryObjectFactory程序里面实现的,我来分析一下Hibernate的绑定JNDI的过程:

一.                                                         Hibernate的基本元素

Hibernate配置方式

  我们获得SessionFactory一般是这样写代码:

Configuration—hibernate.cfg.xml

Hibernate给人的感受是灵活的,要达到同一个目的,我们可以使用几种不同的办法。就拿Hibernate配置来说,常用的有如下三种方式,任选其一。

  Configuration conf = new Configuration().addClass(Cat.class);
  SessionFactory sf = conf.buildSessionFactory();

1.   hibernate.cfg.xml 或 hibernate.properties 默认的配置文件

只需选择一种形式的配置方式,
properties形式的文件不配置mapping子节点,且不使用xml的格式:

一个典型的xml配置文件如下:

 

<?xml version=’1.0′ encoding=’UTF-8′?>

<!DOCTYPE hibernate-configuration PUBLIC

          “-//Hibernate/Hibernate Configuration DTD 3.0//EN”

         
“;

 

<!– Generated by MyEclipse Hibernate Tools.                   –>

<hibernate-configuration>

    <session-factory>

       <property name=”connection.username”>root</property>

       <property name=”connection.url”>

           jdbc:mysql://localhost:3306/test

       </property>

       <property name=”dialect”>

           org.hibernate.dialect.MySQLDialect

       </property>

       <property name=”connection.password”>root</property>

       <property name=”connection.driver_class”>

           org.gjt.mm.mysql.Driver

       </property>

       <property name=”show_sql”>true</property>

       <property
name=”hibernate.hbm2ddl.auto”>create</property>

       <mapping resource=”cn/thinkmore/hibernate/pojo/tuser.hbm.xml”
/>

<!—

   other mapping element…

–>

    </session-factory>

</hibernate-configuration>

 

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE hibernate-mapping PUBLIC

“-//Hibernate/Hibernate Mapping DTD 3.0//EN”

“;

<hibernate-mapping>

    <class name=”hibernate3.pojo.Tuser” table=”t_user”>

       <id column=”ID” name=”id” type=”java.lang.String”>

           <generator class=”uuid.hex” />

       </id>

       <property column=”NAME” name=”name” type=”java.lang.String”
/>

       <property column=”EMAIL” name=”email” type=”java.lang.String”
/>

    </class>

</hibernate-mapping>

 

对应的hibernate.properties文件为:

connection.username root

connection.url jdbc:mysql://localhost:3306/test

dialect org.hibernate.dialect.MySQLDialect

connection.password root

connection.driver_class org.gjt.mm.mysql.Driver

show_sql true

在 hibernate.cfg.xml 中加入元素
、,放置在类路径(classpath)的根目录下。

  首先是new
Configuration()创建一个Configuration,在这个构造器里面进行配置文件(hibernate.properties)的读取工作,然后保存到一个Properties对象里面去,和JNDI相关的是这个属性:

2.   配置文件—–数据库连接配置

可以选择JDBC配置或者JNDI中的一种:

JDBC配置项:

dialect  —- 数据库适配器, 每个数据库略有不同

connection.driver_class  — 数据库驱动类

connection.url  — 数据库URL

connection.username — 数据库用户名

connection.password — 数据库登陆密码(对应的)

 

JNDI配置项:

dialect  —- 数据库适配器, 同上

connection.datasource  —数据库JNDI名称

connection.username — 数据库用户名, 同上

connection.password — 数据库登陆密码(对应的) , 同上

将 hibernate.properties 放置放在类路径的根目录下。

  hibernate.session_factory_name hibernate/session_factory

3.   配置文件—–数据库连接池配置

目前Hibernate支持的4种连接池组件,
除了Hibernate默认的都需要指出hibernate.connection.provider_class.

 

hibernate默认的(hibernate.properties文件为例):

    hibernate.connection.pool_size 2

 

 

C3P0

 

 

Dbcp(推荐)

 

 

Proxool

可编程的配置方式,即在程序中配置Hibernate的启动参数、加载映射文件,需要用Configuration接口来实现这一方式。

  接着调用buildSessionFactory()方法,该方法检查一下配置信息,然后调用SessionFactoryImpl的一个构造器。在构造器里面注意下面两行代码:

4.   Transaction(事务管理)

hibernate.transaction.factory_class配置Transaction实例工厂类二选一.

 

JDBC的事务处理机制:

hibernate.transaction.factory_class  org.hibernate.transaction.
JDBCTransaction

 

使用JTA

hibernate.transaction.factory_class  org.hibernate.transaction.
JTATransaction

  jta.UserTransaction jta/usertransaction

 

使用hibernate.cfg.xml是我比较喜欢的方式,一方面xml天生的优势——良好的可读性,让配置的意图一目了然。另一方面这是官方推荐使用的,如果同时在hibernate.cfg.xml和hibernate.properties对Hibernate进行了配置,那么前者将覆盖后者。

  name = properties.getProperty(Environment.SESSION_FACTORY_NAME);
  SessionFactoryObjectFactory.addInstance(uuid, name, this,
properties);

配置, Session相关

hibernate.properties可以非常的简洁明了,并且有一种linux配置文件的风格。以#开始一行的注释,用键值对的方式存储配置参数。

  调用了SessionFactoryObjectFactory的addInstance方法,并且把自身(SessionFactory的实例)作为参数传递。最后在addInstance方法可以看到如下代码:

5.   Configuration类(org.hibernate.cfg.Configuration类)

为了获取SessionFactory, 一般只需执行一次. xml形式的配置文件比较方便:

 

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

也可以指定一个文件进行加载,而不使用默认的hibernate.cfg.xml文件,

java.io.File file = new java.io.File(“…..”);

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

对应properties形式的配置方式必须手工加载映射文件,比如:

Configuration config=new Configuration();

config.addClass(TUser.class);

对于这两种方式,结果都是一样的。只是看个人喜好。关于配置参数我们稍后讨论。

  Context ctx = NamingHelper.getInitialContext(properties);
  NamingHelper.bind(ctx, name, instance);

6.   SessionFactory(org.hibernate.SessionFactory接口)

SessionFactory顾名思义, 就是session的工厂类.
创建SessionFactory的实例就是调用已经装载了配置信息的Configuration对象的buildSessionFactory()方法:

 

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

SessionFactory sessionFactory = config.buildSessionFactory();

 

Hibernate2中buildSessionFactory()方法声明了抛出异常.

SessionFactory对象中保存了配置信息. 如果要使用多个数据库,
需要针对每个数据库分别建立对应的SessionFactory实例,
如果需要动态改变config文件, 则需要动态重建SessionFactory的实例.

SessionFactory中还保存了二级数据缓存和Statement Pool, 它是线程安全的,
所以一个数据库的SessionFactory一般作为单实例存在.

Configuration类

  instance
就是SessionFactory的实例,通过读源代码,可以清楚的看到Hibernate是在conf.buildSessionFactory()的时候通过一系列类方法调用,把创建的SessionFactory实例绑定到配置文件(hibernate.properties)中
hibernate.session_factory_name属性指定的名称上的,因此可见Hibernate自身是具有JNDI的动态绑定功能的。但是Hibernate需要获得一个SessionFactory实例用于绑定,而这个SessionFactory实例需要我们写代码进行预先创建,并且必须保证该过程要在所有其它要从JNDI上获得SessionFactory实例的程序之前完成。

7.   得到Session, Session的线程局部化

Session newSession = sessionFactory.openSession();

Session代表Hibernate的会话, 作用就像JDBC的Conection对象.
Hibernate2的find方法已经被废除.

Session是非线程安全的,
所以不应该对同一个Session实例进行多线程同时调用.

HibernateUtil和静态SessionFactory一起工作,
ThreadLocal管理Hibernate
Session。通过ThreadLocal类型来实现Session的线程独立.
ThreadLocal在JVM内部维护一个Map, key是当前的线程对象,
value是在当前线程中调用ThreadLocal对象的set方法时传递的参数. 
当调用ThreadLocal对象的get方法时,
ThreadLocal对象会把当前线程对象的引用作为key从Map中取出绑定的对象.

package cn.thinkmore.hibernate.session;

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

 

public class HibernateUtil{

    private static SessionFactory sessionFactory;

    static {

       sessionFactory = new
Configuration().configure().buildSessionFactory();

    }

 

private static final ThreadLocal<Session>
SESSIONCONTAINER = new ThreadLocal<Session>();

 

    public static Session currentSession() {

       Session se = (Session) SESSIONCONTAINER.get();

       if (null == se) {

           se = sessionFactory.openSession();

           SESSIONCONTAINER.set(se);

       }

       return se;

    }

 

    public static void closeSession() {

       Session se = (Session) SESSIONCONTAINER.get();

       if (null == se) {

       //  SESSIONCONTAINER.set(null);

       } else {

           se.close();

       }

    }

}

在WebApplication中为了更好的管理Session的生命周期,
可以把静态ThreadLocal对象定义在过滤器中,
在进入过滤器时调用其set(新的Session); 执行doFilter后,
在调用get方法去除Session并进行关闭.在业务操作中,统一用过滤器的静态ThreadLocal获取Session,
就保证了每一个request对象只能使用一个独立的Session.

由于一些EJB可能会运行在同一个事务但不同线程的环境中,
所以这个方法不能照搬到EJB环境中.建议在托管环境中,将SessionFactory绑定到JNDI上.

org.hibernate.cfg.Configuration实例的作用是对Hibernate进行配置,以及对它进行启动。在Hibernate的启动过程中,Configuration类的实例首先读取Hibernate配置文件,加载配置信息,然后加载映射文件,创建一个SessionFactory对象。

  因此对于任何App
Server来说,我们都不必去管JNDI名称的绑定过程,只需要保证预先创建一个SessionFactory实例出来就够了,剩下的工作
Hibernate会做的。那么如何确保预创建SessionFactory实例呢,如果是Servlet,可以配置一个初始化的Servlet,只要把

实例被设计成启动期间(startup-time)对象,一旦SessionFactory
创建完成它就被丢弃了。

  Configuration conf = new Configuration().addClass(Cat.class);
  SessionFactory sf = conf.buildSessionFactory();

要使用一个Configuration对象,要为它设置两个方面的内容:

  这样的代码加进去就可以了。如果是包含EJB的的复杂的J2EE应用,可能需要依靠App
Server的功能来保证预创建SessionFactory实例。

数据库连接属性

hbm.xml或pojo类

Configuration常用操作函数

1.加载Hibernate配置文件

Configuration cfg=new
Configuration().configure(“/etc/hibernate.cfg.xml”);

或者

Configuration cfg=new
Configuration().configure(“/etc/hibernate.properties”);

2.为Configuration指定映射文件

cfg.addResource(“test/User.hbm.xml”);

3.为Configuration指定POJO类,Order.hbm.xml根Order.java一个目录

cfg.addClass(test.Order.class);

4.为Configuration指定Hibernate配置属性,当然我们加载了配置文件就不能使用这个方法了。

Configuration cfg = new Configuration()

.addClass(test.User.class)

.setProperty(“hibernate.dialect”, “org.hibernate.dialect.MySQLDialect”)

.setProperty(“hibernate.connection.datasource”,
“java:comp/env/jdbc/test”)

.setProperty(“hibernate.order_updates”, “true”);

5.获得SessionFactory

SessionFactory sessions = cfg.buildSessionFactory();

当所有映射定义被 Configuration
解析后,应用程序必须获得一个用于构造org.hibernate.Session
实例的工厂SessionFactory。这个工厂将被应用程序的所有线程共享,线程安全的全局对象,只需要被实例化一次。单例模式。

Hibernate 允许你的应用程序创建多个SessionFactory 实例。这对
使用多个数据库的应用来说很有用。

hibernate.cfg.xml

hibernate.cfg.xml在文档开头的DTD(文档类型定义)是很复杂的。我们并不需要去理会和记忆他。你可以直接copy它。

hibernate.cfg.xml文档以为根元素,你可以在其子元素中

加入元素来配置各种参数。

加入加载映射文件,resource代表映射文件的路径。

一个hibernate.cfg.xml例子:

                    jdbc:mysql://localhost:3306/test        root       
klguang@mysql        com.mysql.jdbc.Driver               
org.hibernate.dialect.MySQLDialect                10               
thread                            org.hibernate.cache.NoCacheProvider   
                    true                update        none             
             

hibernate.properties

对于hibernate.properties作为配置文件的方式,我是不推荐新手使用的。因为,其可读性差,另外众多的配置参数会让初学者不知道如何下手。

在Hibernate发布包的project/etc/,提供了一个hibernate.properties文件,该文件列出了Hibernate
的所有配置参数,但都是用#注释掉了。每一行是一个配置参数,以键值对的方式存在,空格前是key,空格后是value,我们应该将空格改为等号。

对每一个配置参数,文件里都有详细的解释。我们只需要将见面#去掉,并修改其value就可以了。

一个hibernate.properties例子:

#数据库使用的驱动类

hibernate.connection.driver_class=com.mysql.jdbc.Driver

#数据库连接串

hibernate.connection.url=jdbc:mysql://localhost:3306/db

#数据库连接的用户名

hibernate.connection.username=user

#数据库连接的密码

hibernate.connection.password=password

#数据库使用的方言

hibernate.dialect=net.sf.hibernate.dialect.MySQLDialect

#是否打印SQL语句

hibernate.show_sql=true

javax.persistence.validation.mode=none

hibernate.properties没有提供加载映射文件的方式。因此需要通过Configuration的.addResource()方法来加载映射文件或POJO类,Hibernate会自动找到另一方,前提映射文件和POJO类在同一包(目录)中。

Configuration cfg = new Configuration();

cfg.configure(“/etc/hibernate.properties”);

cfg.addResource(“test/User.hbm.xml”);

cfg.addClass(test.Order.class);

Hibernate配置参数详解

Hibernate JDBC 属性

属性名用途

hibernate.connection.driver_classJDBC driver class

hibernate.connection.urlJDBC URL

hibernate.connection.usernamedatabase user

hibernate.connection.password数据库用户密码

hibernate.connection.pool_sizemaximum number of pooled connections

Hibernate 数据源属性

属性名用途

hibernate.connection.datasource数据源JNDI 名字

hibernate.jndi.url JNDI提供者的URL(可选)

hibernate.jndi.class JNDIInitialContextFactory 类(可选)

hibernate.connection.username数据库用户(可选)

hibernate.connection.password数据库密码(可选)

可选的配置属性

有大量属性能用来控制 Hibernate
在运行期的行为。它们都是可选的,并拥有适当的默认值。

属性名用途可选值

()内为默认

hibernate.dialect允许Hibernate针对特定的关系数据库生成优化的SQL的org.hibernate.dialect.Dialect的类名。

例如:org.hibernate.dialect.MySQLDialect

hibernate.show_sql输出所有SQL语句到控制台。true|false

(false)

hibernate.format_sql在log和console中打印出更漂亮的SQL。true|false

(false)

hibernate.default_catalog在生成的SQL中,将给定的catalog附加于非全限定名的表名上

hibernate.session_factory_nameorg.hibernate.SessionFactory创建后,将自动使用这个名字绑定到JNDI中。

hibernate.max_fetch_depth为单向关联(一对一,多对一)的外连接抓取(outer
join fetch)树设置最大深度。0到3

hibernate.default_batch_fetch_size为Hibernate关联的批量抓取设置默认数量。4、8、16

hibernate.default_entity_mode为由这个SessionFactory打开的所有Session指定默认的实体表现模式。dynamic-map,dom4j,pojo

hibernate.order_updates强制Hibernate按照被更新数据的主键,为SQL更新排序。这么做将减少在高并发系统中事务的死锁。true|false

hibernate.generate_statistics如果开启,Hibernate将收集有助于性能调节的统计数据。true|false

hibernate.use_identifier_rollback如果开启,在对象被删除时生成的标识属性将被重设为默认值。true|false

hibernate.use_sql_comments如果开启,Hibernate将在SQL中生成有助于调试的注释信息,默认值为false。true|false

(false)

Hibernate JDBC 和连接(connection)属性、Hibernate 缓存属性、Hibernate
事务属性等主要用于提升性能,并且Hibernate有适当的默认值。入门者可以忽略这些设置,等学到一定阶段,你可以参考官方文档进行适当配置。

+289683894裙交流学习,领取更多资料

发表评论

电子邮件地址不会被公开。 必填项已用*标注