范冰冰古装戏难产图片:Relucent的博客 - JavaEye技术网站

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 23:30:20
2009-12-03缩略显示

监控和剖析数据库操作 -- P6Spy、SQL Profiler、IronTrack SQL 使用简介

原文来源:http://www.ibm.com/developerworks/cn/java/j-lo-p6spy/index.html

 

  • 12:51
  • 浏览 (89)
  • 评论 (0)
  • 分类: Java
2009-12-03缩略显示

关于hibernate的二级缓存学习

本文转载自:http://vinnyz.javaeye.com/blog/248607

  

原文题目:Speed Up Your Hibernate Application with Second-Level Caching
原文来源:http://www.devx.com/dbzone/Article/29685/1954
作者简介:John Ferguson Smart,参与过很多企业和政府大型的的J2EE项目,他的专长包括J2EE的架构,开发和IT项目管理。他也有很多的在JAVA的开源技术方面的经验。这是他技术blog的链接www.jroller.com/page/wakaleo

原文翻译如下:

通过二级缓存来加快你的hibernate应用程序

新的hibernate开发人员有时并不知道hibernate的缓存结果并没有充分的使用它,尽管如此,当我们正确使用缓存的时候,它能够变为加速hibernate应用程序最有力的武器之一。

在web应用程序中和大数据量的数据库交互经常导致性能问题。hibernate是一种高性能的,提供对象/关系持久化和查询的服务,但是如果没有帮助就不会解决所有性能上的问题。在很多情况下,二级缓存就是hibernate潜在的需要来实现所有的性能上的处理。这篇文章将研究hibernate的缓存功能并且展现怎么使用才能明显的提升应用程序的性能。

缓存介绍

缓存被广泛用于数据库应用领域。缓存的设计就是为了通过存储已经从数据库读取的数据来减少应用程序和数据库之间的数据流量,而数据库的访问只在检索的数据不在当前缓存的时候才需要。如果数据库以一些方式进行更新和修改的话,那么应用程序可能需要每隔一段时间清空缓存,因为它没有方法知道缓存里的数据是不是最新的。

Hibernate缓存

从对象来说,hibernate用了两种缓存的方法:一级缓存和二级缓存。一级缓存和Session对象关联,二级缓存和Session Factory对象关联。默认情况下,hibernate使用一级缓存来作为一次事务预处理的基础。hibernate使用它主要是为了减少在一次给定的事务中需要被生成的SQL查询语句。例如,一个对象在同一个事务中被修改好几次,hibernate会在事务结束的时候只生成一条SQL更新语句,它包含了所有修改内容。这篇文章主要介绍二级缓存。为了减少和数据库的交互,二级缓存保存已经读出的对象在各个事务之间的Session Factory级别。这些对象在整个程序中都可以得到,而不仅是用户运行查询的时候。这种方式,每次查询返回的对象都已经被载入了缓存,一次或多次潜在的数据库事务可以避免。

除此之外,你可以使用查询级别缓存如果你需要缓存的实际的查询结果,而不仅仅是持久化对象。

缓存的实现

缓存是软件中复杂的部分,市场上也提供了相当数量的选择,包括基于开源的和商业的。hibernate提供了以下开源的缓存实现,如下:
    * EHCache (org.hibernate.cache.EhCacheProvider)
    * OSCache (org.hibernate.cache.OSCacheProvider)
    * SwarmCache (org.hibernate.cache.SwarmCacheProvider)
    * JBoss TreeCache (org.hibernate.cache.TreeCacheProvider)

不同的缓存提供了在性能,内存使用和配置的可扩展性方面不同的能力
EHCache是一种快速的,轻量级的,容易上手的缓存。它支持只读和读写缓存,基于内存和硬盘的数据储存。但是,它不支持簇。
OSCache是另一个开源的缓存解决方案,它是一个也为jsp页面和任意对象提供缓存功能的大的开发包的一部分。它本身也是一个强大和灵活的开发包,像EHCache一样,也支持只读和读写缓存,基于内存和硬盘的数据储存。它通过JavaGroups或者JMS也提供了对簇的基本支持。
SwarmCache是一种基于簇的解决方案,它本身也基于集群服务实体间通信的通信协议。它提供了只读和没有限制的读写缓存(下一部分将解释这个名词)。这种类型的缓存对那些典型的读操作比写操作多的多的应用程序是适合的。
JBoss TreeCache是一种强大的两重性(同步的或异步的)和事务性的缓存。使用此实现如果你确实需要一种事务能力的缓存架构。

另一种值得提及的缓存实现是商业化的Tangosol Coherence cache。

缓存策略

一旦你选择了你的缓存实现,你需要指定你的缓存策略。以下是四种缓存策略:
只读:这种策略对那种数据被频繁读取但是不更新是有效的,这是到目前为止最简单,表现最好的缓存策略。
读写:读写缓存对假设你的数据需要更新是必要的。但是读写需要比只读缓存花费更多的资源。在非JTA的事务环境中,每一个事务需要完成在Session.close() 或Session.disconnect()被调用的时候。
没有限制的读写:这个策略不能保证2个事务不会同时的修改相同的数据。因此,它可能对那些数据经常被读取但只会偶尔进行写操作的最适合。
事务性:这是个完全事务性的缓存,它可能只能被用在JTA环境中。

对每一个缓存实现来说,支持策略不是唯一的。图一展现了对
缓存实现可供的选择。


文章余下的部分用来展示一个使用EHCache单一的JVM缓存。

缓存配置

为了启用二级缓存,我们需要在hibernate.cfg.xml配置文件中定义hibernate.cache.provider_class属性,如下
Java代码
  1.   
  2.        
  3.         ...   
  4.            
  5.             org.hibernate.cache.EHCacheProvider   
  6.            
  7.         ...   
  8.        
  9.   
Java代码
  1.   
  2.        
  3.         ...   
  4.         "hibernate.cache.provider_class">   
  5.             org.hibernate.cache.EHCacheProvider   
  6.            
  7.         ...   
  8.        
  9.   

为了在hibernate3中测试的目的,你还要使用hibernate.cache.use_second_level_cache属性,它可以让你启用(和关闭)二级缓存。默认情况下,二级缓存是启用的同时使用EHCache。

一个实际应用

这个例子演示的程序包含四张简单的表:国家列表,机场列表,员工列表,语言列表。每个员工被分配了一个国家,并且能说很多语言。每个国家能有任意数量的机场。

                          图一展现了UML类图

                         图二展现了数据库架构

这个例子的源代码(http://assets.devx.com/sourcecode/14239.tgz)包括了以下的SQL脚本,你需要用它创建和实例化数据库。
    * src/sql/create.sql: 创建数据库的SQL脚本
    * src/sql/init.sql: 测试数据
   
   安装Maven2
在写的时候,Maven2安装目录看来好像缺少了一些jars。为了解决这个问题,在应用程序源码的根目录里找到那些缺少的jars。把它们安装到Maven2的文件里,到应用程序的目录下,执行以下的命令
    
$ mvn install:install-file -DgroupId=javax.security -DartifactId=jacc
-Dversion=1.0
    -Dpackaging=jar -Dfile=jacc-1.0.jar
$ mvn install:install-file -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B
    -Dpackaging=jar -Dfile=jta-1.0.1B.jar




建立一个只读缓存

从简单的开始,下面是country类的hibernate映射。
  Java代码
  1. package="com.wakaleo.articles.caching.businessobjects">   
  2.     <class name="Country" table="COUNTRY" dynamic-update="true">   
  3.         "implement-equals">true       
  4.         "read-only"/>   
  5.   
  6.         "id" type="long" unsaved-value="null" >   
  7.             "cn_id" not-null="true"/>   
  8.             class="increment"/>   
  9.            
  10.   
  11.        "cn_code" name="code" type="string"/>   
  12.        "cn_name" name="name" type="string"/>   
  13.   
  14.       "airports">   
  15.        "cn_id"/>   
  16.        class="Airport"/>   
  17.          
  18.     class>   
  19.   


假设你要显示国家列表。你可以通过CountryDAO类中一个简单的方法实现,如下


 

Java代码
  1. public class CountryDAO {   
  2.     ...    
  3.     public List getCountries() {   
  4.         return SessionManager.currentSession()   
  5.                        .createQuery(   
  6.                           "from Country as c order by c.name")   
  7.                        .list();   
  8.     }   
  9. }  

因为这个方法经常被调用,所以你要知道它在压力下的行为。写一个简单的单元测试来模拟5次连续的调用。 Java代码
  1. public void testGetCountries() {   
  2.         CountryDAO dao = new CountryDAO();   
  3.         for(int i = 1; i <= 5; i++) {   
  4.             Transaction tx = SessionManager.getSession().beginTransaction();   
  5.             TestTimer timer = new TestTimer("testGetCountries");   
  6.             List countries = dao.getCountries();   
  7.             tx.commit();   
  8.             SessionManager.closeSession();   
  9.             timer.done();   
  10.             assertNotNull(countries);   
  11.             assertEquals(countries.size(),229);   
  12.         }   
  13.     }  

你能够运行这个测试通过自己喜欢的IDE或者Maven2的命令行(演示程序提供了2个Maven2的工程文件)。这个演示程序通过本地的mysql来测试。当你运行这个测试的时候,应该得到类似以下的一些信息:
$mvn test -Dtest=CountryDAOTest
...
testGetCountries: 521 ms.
testGetCountries: 357 ms.
testGetCountries: 249 ms.
testGetCountries: 257 ms.
testGetCountries: 355 ms.
[surefire] Running com.wakaleo.articles.caching.dao.CountryDAOTest
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 3,504 sec

可以看出每次调用大概花费半秒的时间,对大多数标准来说还是有点迟缓的。国家的列表很可能不是经常的改变,所以这个类可以作为只读缓存一个好的候选。所以加上去

你可以启用二级缓存用以下两种方法的任意一种

1.你可以在*.hbm.xml里启用它,使用cache的属性 Java代码
  1. package="com.wakaleo.articles.caching.businessobjects">   
  2.          <class name="Country" table="COUNTRY" dynamic-update="true">   
  3.         "implement-equals">true   
  4.         "read-only"/>   
  5.             ...                    
  6.         class>   
  7.       


2.你可以存储所有缓存信息在hibernate.cfg.xml文件中,使用class-cache属性 Java代码
  1.   
  2.        
  3.         ...   
  4.         "hibernate.cache.provider_class">   
  5.             org.hibernate.cache.EHCacheProvider   
  6.            
  7.         ...   
  8.         <class-cache    
  9. class="com.wakaleo.articles.caching.businessobjects.Country"  
  10. usage="read-only"  
  11.         />   
  12.        
  13.   


下一步,你需要为这个类设置缓存规则,这些规则决定了缓存怎么表现的细节。这个例子的演示是使用EHCache,但是记住每一种缓存实现是不一样的。
EHCache需要一个配置文件(通常叫做ehcache.xml)在类的根目录。EHCache配置文件的详细文档可以看这里(http://ehcache.sourceforge.net/documentation)。基本上,你要为每个需要缓存的类定义规则,以及一个defaultCache在你没有明确指明任何规则给一个类的时候使用。

对第一个例子来说,你可以使用下面简单的EHCache配置文件 Java代码
  1.   
  2.   
  3.     "java.io.tmpdir"/>   
  4.   
  5.     
  6.         maxElementsInMemory="10000"  
  7.         eternal="false"  
  8.         timeToIdleSeconds="120"  
  9.         timeToLiveSeconds="120"  
  10.         overflowToDisk="true"  
  11.         diskPersistent="false"  
  12.         diskExpiryThreadIntervalSeconds="120"  
  13.         memoryStoreEvictionPolicy="LRU"  
  14.         />   
  15.            
  16.     "com.wakaleo.articles.caching.businessobjects.Country"  
  17.         maxElementsInMemory="300"  
  18.         eternal="true"  
  19.         overflowToDisk="false"  
  20.         />   
  21.   
  22.   


这个文件为countries类建立一个基于内存最多300单位的缓存(countries类包含了229个国家)。注意缓存不会过期('eternal=true'属性)。现在通过返回的结果看下缓存的表现

$mvn test -Dtest=CompanyDAOTest
...
testGetCountries: 412 ms.
testGetCountries: 98 ms.
testGetCountries: 92 ms.
testGetCountries: 82 ms.
testGetCountries: 93 ms.
[surefire] Running com.wakaleo.articles.caching.dao.CountryDAOTest
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 2,823 sec

正如你期盼的那样,第一次查询没有改变因为需要加载数据。但是,随后的几次查询就快多了。

后台

在我们继续之前,看下后台发生了什么非常有用。一件事情你需要知道的是hibernate缓存不储存对象实例,代替的是它储存对象“脱水”的形式(hibernate的术语),也就是作为一系列属性值。以下是一个countries缓存例子的内容

{
  30  => [bw,Botswana,30],
  214 => [uy,Uruguay,214],
  158 => [pa,Panama,158],
  31  => [by,Belarus,31]
  95  => [in,India,95]
  ...
}

注意每个ID是怎么样映射到拥有属性值的数组的。你可能也注意到了只有主要的属性被储存了,而没有airports属性,这是因为airports属性只是一个关联:对其他持久化对象一系列的引用。

默认情况下,hibernate不缓存关联。而由你决定来缓存哪个关联,哪个关联需要被重载当缓存对象从二级缓存获得的时候。

关联缓存是一个非常强大的功能。下一部分我们将介绍更多的内容。

和关联缓存一起工作

假设你需要显示一个给定的国家的所有的员工(包括员工的名字,使用的语言等)。以下是employee类的hibernate映射 Java代码
  1. package="com.wakaleo.articles.caching.businessobjects">   
  2.     <class name="Employee" table="EMPLOYEE" dynamic-update="true">   
  3.         "implement-equals">true       
  4.   
  5.        "id" type="long" unsaved-value="null" >   
  6.             "emp_id" not-null="true"/>   
  7.             class="increment"/>   
  8.           
  9.   
  10.      "emp_surname" name="surname" type="string"/>   
  11.      "emp_firstname" name="firstname" type="string"/>   
  12.           
  13.      "country"  
  14.                   column="cn_id"  
  15.                   class="com.wakaleo.articles.caching.businessobjects.Country"     
  16.               not-null="true" />   
  17.                    
  18.             
  19.      "languages" table="EMPLOYEE_SPEAKS_LANGUAGE" lazy="false">   
  20.          "emp_id"/>   
  21.                 "lan_id" class="Language"/>   
  22.                                
  23.     class>   
  24.   


假设你每次使用employee对象的时候需要得到一个员工会说的语言。强逼hibernate自动载入关联的languages集合,你设置了lazy属性为false()。你还需要一个DAO类来得到所有employee,以下的代码来帮你实现 Java代码
  1. public class EmployeeDAO {   
  2.   
  3.     public List getEmployeesByCountry(Country country) {   
  4.         return SessionManager.currentSession()   
  5.          .createQuery(   
  6.               "from Employee as e where e.country = :country "  
  7.                 + " order by e.surname, e.firstname")   
  8.          .setParameter("country",country)   
  9.          .list();   
  10.     }   
  11. }  


下一步,写一些简单的单元测试来看它怎么表现。正如前面的例子一样,你需要知道它被重复调用时候的性能 Java代码
  1. public class EmployeeDAOTest extends TestCase {   
  2.   
  3.     CountryDAO countryDao = new CountryDAO();   
  4.     EmployeeDAO employeeDao = new EmployeeDAO();   
  5.   
  6.     /**  
  7.      * Ensure that the Hibernate session is available  
  8.      * to avoid the Hibernate initialisation interfering with  
  9.      * the benchmarks  
  10.      */  
  11.     protected void setUp() throws Exception {          
  12.         super.setUp();   
  13.         SessionManager.getSession();   
  14.     }   
  15.   
  16.     public void testGetNZEmployees() {   
  17.         TestTimer timer = new TestTimer("testGetNZEmployees");   
  18.         Transaction tx = SessionManager.getSession().beginTransaction();   
  19.         Country nz = countryDao.findCountryByCode("nz");   
  20.         List kiwis = employeeDao.getEmployeesByCountry(nz);   
  21.         tx.commit();   
  22.         SessionManager.closeSession();   
  23.         timer.done();   
  24.     }   
  25.   
  26.     public void testGetAUEmployees() {   
  27.         TestTimer timer = new TestTimer("testGetAUEmployees");   
  28.         Transaction tx = SessionManager.getSession().beginTransaction();   
  29.         Country au = countryDao.findCountryByCode("au");   
  30.         List aussis = employeeDao.getEmployeesByCountry(au);       
  31.         tx.commit();   
  32.         SessionManager.closeSession();   
  33.         timer.done();   
  34.     }   
  35.   
  36.     public void testRepeatedGetEmployees() {   
  37.         testGetNZEmployees();   
  38.         testGetAUEmployees();   
  39.         testGetNZEmployees();   
  40.         testGetAUEmployees();   
  41.     }   
  42. }  


如果你运行上面的代码,你会得到类似以下的一些数据

$mvn test -Dtest=EmployeeDAOTest
...

testGetNZEmployees: 1227 ms.
testGetAUEmployees: 883 ms.
testGetNZEmployees: 907 ms.
testGetAUEmployees: 873 ms.
testGetNZEmployees: 987 ms.
testGetAUEmployees: 916 ms.
[surefire] Running com.wakaleo.articles.caching.dao.EmployeeDAOTest
[surefire] Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 3,684 sec

所以对一个国家载入大约50个员工需要花费大约一秒的时间。这种方法显然太慢了。这是典型的N+1的查询问题。如果你启用SQL日志,你会发现对employee表的一次查询,紧跟着对language表几百次的查询,无论什么时候hibernate从缓存里得到一个employee对象,它都会重载所有关联的language。那怎么提升它的性能呢?第一件要做的事就是对employee启用读写缓存,如下    Java代码
  1. package="com.wakaleo.articles.caching.businessobjects">   
  2.         <class name="Employee" table="EMPLOYEE" dynamic-update="true">   
  3.         "implement-equals">true   
  4.         "read-write"/>   
  5.             ...                    
  6.         class>   
  7.   


你还应该对language类启用缓存。只读缓存如下 Java代码
  1. package="com.wakaleo.articles.caching.businessobjects">   
  2.         <class name="Language" table="SPOKEN_LANGUAGE" dynamic-update="true">   
  3.         "implement-equals">true       
  4.         "read-only"/>   
  5.             ...                    
  6.         class>   
  7.   


然后你需要配置缓存的规则通过加入以下的内容到ehcache.xml文件中
  Java代码
  1. "com.wakaleo.articles.caching.businessobjects.Employee"  
  2.         maxElementsInMemory="5000"  
  3.         eternal="false"  
  4.         overflowToDisk="false"  
  5.         timeToIdleSeconds="300"  
  6.         timeToLiveSeconds="600"  
  7.     />   
  8.     "com.wakaleo.articles.caching.businessobjects.Language"  
  9.         maxElementsInMemory="100"  
  10.         eternal="true"  
  11.         overflowToDisk="false"  
  12.     />  


但是还是没有解决N+1的查询问题:当你载入一个employee对象的时候大约50次的额外查询还是会执行。这里你就需要在Employee.hbm.xml映射文件里关联的language启用缓存,如下
  Java代码
  1. package="com.wakaleo.articles.caching.businessobjects">   
  2.     <class name="Employee" table="EMPLOYEE" dynamic-update="true">   
  3.         "implement-equals">true       
  4.   
  5.       "id" type="long" unsaved-value="null" >   
  6.             "emp_id" not-null="true"/>   
  7.             class="increment"/>   
  8.          
  9.   
  10.     "emp_surname" name="surname" type="string"/>   
  11.     "emp_firstname" name="firstname" type="string"/>   
  12.           
  13.     "country"  
  14.              column="cn_id"  
  15.                class="com.wakaleo.articles.caching.businessobjects.Country"     
  16.             not-null="true" />   
  17.                    
  18.            
  19.       "languages" table="EMPLOYEE_SPEAKS_LANGUAGE" lazy="false">   
  20.         "read-write"/>   
  21.         "emp_id"/>   
  22.             "lan_id" class="Language"/>   
  23.                                        
  24.     class>   
  25.   


通过这个配置,你就能得到几近最优的性能

$mvn test -Dtest=EmployeeDAOTest
...
testGetNZEmployees: 1477 ms.
testGetAUEmployees: 940 ms.
testGetNZEmployees: 65 ms.
testGetAUEmployees: 65 ms.
testGetNZEmployees: 76 ms.
testGetAUEmployees: 52 ms.
[surefire] Running com.wakaleo.articles.caching.dao.EmployeeDAOTest
[surefire] Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 0,228 sec

查询缓存
在确定的情况下,缓存一次查询的正确结果是非常有用的,不仅是只是个确定的对象。例如,getCountries()方法在每次调用的时候或许会返回相同的国家列表。所以,除了缓存country类之外,你也应该缓存查询结果本身。

为了实现这个目标,你需要在hibernate.cfg.xml文件中设置hibernate.cache.use_query_cache属性为true,如下

   true

然后需要在对任何查询缓存的时候使用setCacheable()方法,如下
  Java代码
  1. public class CountryDAO {   
  2.   
  3.     public List getCountries() {   
  4.         return SessionManager.currentSession()   
  5.                              .createQuery("from Country as c order by c.name")   
  6.                      .setCacheable(true)   
  7.                              .list();   
  8.     }   
  9. }  


但是,它不能预知到其他程序对数据库任何的改变。所以你不应该使用任何二级缓存(或为类和集合的缓存设置简短的过期时间)如果你的数据总是要保证最新的状态。

正确的使用hibernate缓存

缓存是一种强大的技术,hibernate提供了一种强大的,灵活的,不显眼的方式来实现它。即使对很多简单的例子来说默认的设置能使实际的性能得到提升。但是,像很多强大工具一样,hibernate还是需要一些思考和微调来得到最优的结果,而缓存像其他的优化技术一样,应该使用一种可扩展,测试驱动的方法所实现。当正确使用的时候,少量的缓存实现,能最大程度的提高你的程序运行。

  • 10:02
  • 浏览 (138)
  • 评论 (0)
  • 分类: Hibernate
2009-12-03缩略显示

Hibernate文档笔记

 

一、对象定义

1.org.hibernate.SessionFactory

对于单个数据库,被编译的映射,是一个线程安全的缓冲区。是一个Session和ConnectionProvider客户端的工厂。拥有可选的对过程级和集群级重复利用的数据的缓存(二级缓存)。

2.org.hibernate.Session

单线程、短生命周期的在应用程序和持久化存储系统之间的一个会话对象。封装了一个JDBC连接。是一个事务的工厂。拥有强制的对持久化对象的缓存(一级缓存),当通过标识浏览对象之间关系和查找对象时使用。

3.Persistent objects and collections

包含执久化状态和业务功能的短生命周期的、单线程对象。可以是POJOs,通常是和Session(严格说,是单个Session)相关联的对象。Session一关闭,他们将和Session分离,可以自由的使用在应用层的任何地方。(也就是说,作为传输对象使用(Transfer Object)。)

4.Transient and detached objects and collections

不和当前Session关联的持久化类的实例。他们可以被应用程序在不持久化时实例化,也可以被关闭的Session实例化。

5.org.hibernate.Transaction (可选)

应用程序用来指定一个原子操作的单线程、短生命周期的对象。低层JDBC、JTA、CORBA事务的抽象程序。在相似的情况下,一个Session可以同时横跨多个事务。事务划分,既可以使用低层的APIs,也可以使用Transaction。

6.org.hibernate.connection.ConnectionProvider (可选)

JDBC连接或JDBC连接池的工厂。低层DataSource和DriverManager的抽象程序。

这个对象不暴露给应用程序,但是应用程序可以被开发者继承和实现。

7.org.hibernate.TransactionFactory (可选)

Transaction实例的工厂。这个对象不暴露给应用程序,但是应用程序可以被开发者继承和实现。

二、实例状态

持久化对象根据持久化上下文的定义,可以有三种不同的状态。Hibernate Session对象是一个持久化上下文。

1.transient

不关联任何的持久化上下文。没有持久化的标识(指主键值Primary key value)。

2.persistent

和当前持久化上下文关联。他有一个持久化标识,多数情况,在数据库中有对应的行。对于特定的持久化上下文,Hibernate保证持久化标识和Java标识(内存中对象的位置)相同。

3.detached

曾经和一个持久化上下文关联,持久化上下文关闭;或者对象在另一个进程中被序列化。他拥有持久化标识,多数情况,在数据库中有对应的行。对于分离对象Hibernate不保证持久化标识和Java标识的对应关系。

三、JMX集成

JMX是Java组件管理的JEE标准。Hibernate可以被JMX服务管理。在发行版本中,Hibernate提供了一个MBean的实现,org.hibernate.jmx.HibernateService。

在JBoss上,你使用JMX可以得到的好处:

1.Session Management

Hibernate Session的生命周期可以自动的绑定到JTA事务范围。这意味着,你不需要手动的打开关闭Session,这成为JBoss EJB拦截器的要完成的工作。在你的代码中,也不用担心事务的划分,当然除非你想要写一个轻便的持久化层,通过使用Hibernate Transaction APIs。你可以调用HibernateContext来访问Session。

2.HAR deployment

通常使用JBoss Service Deployment Descriptor(在EAR或SAR文件中)发布Hibernate JMX Service,它支持Hibernate SessionFactory所有的常用配置选项。无论如何,你还需要在deployment descriptor中描述所有的映射文件。如果你使用可选的HAR Deployment,JBoss将自动检测所有的映射文件在HAR文件中。

四、JCA 支持

Hibernate也可以配置作为一个连接器。该功能是实践型功能。

 

 

五、Contextual Sessions

许多应用程序需要一种和上下文有关联Hibernate session,这样的session是指贯穿于给定环境的上下文中都有效的session。无论如何,贯穿于应用程序应用上下文由什么组成的清晰度不同,不同的上下文针对当前的概念有不同的范围。

使用Hibernate 3.0以前版本的应用程序,趋于使用自已实现的基于ThreadLocal来维护前后关系的session、诸如HibernateUtil的帮助类;或使用基于代理或拦截机制的第三方的框架(Spring或Pico)。

从Hibernate 3.0.1,Hibernate加入了SessionFactory.getCurrentSession()方法。最初,假定使用JTA事务定义了当前session的scope和context。Hibernate团队维护时,给定了成熟的卓越的JTA TransactionManager的实现方式,多数(但不是所有)应用程序应该使JTA transaction management,不论它是否发布到一个JEE容器中。基于这一点,基于用JTA来维护上下文关系中的session应该是必须的。

无论如何,在Hibernate 3.1,SessionFactory.getCurrentSession()之后的处理,是可以被插拔的,也就是说可以session的范围和上下文。新扩展接口(org.hibernate.context.CurrentSessionContext)和新的配置参数(hibernate.current_session_context_class)被加入,允许插拔,也就是说可以定义session的范围和上下文。

细节可以查看org.hibernate.context.CurrentSessionContext的文档。它定义了一个currentSession()方法,负责跟踪与当前上下文相关联的session。Hibernate提供了这个接口的三种实现方式。

1.org.hibernate.context.JTASessionContext

当前session,通过JTA事务跟踪和标识生命周期。这里的处理过程在处理方法上和老JTA是相似的。

2.org.hibernate.context.ThreadLocalSessionContext

当前session,通过当前执行的线程来跟踪。

3.org.hibernate.context.ManagedSessionContext

当前session,通过当前执行的线程来跟踪。你是负责绑定和解除当前session到执行线程通过使用这个类的静态方法。该类不会open、flush、close session。

前两个实现类,提供了“一个session对应一个数据库事务”的编程模式,也就是众所周知的“session-per-request”模式。Hibernate session的开始和结束,是以数据库中事务的执行时间为依据的。如果你使用编程方式划分事务,用简单的JSE需不是JTA,你应该考虑使用Hibernate事务APIs来隐藏低层的事务代码。如果你使用的是JTA,使用JTA的接口来划分事务。如果你在一个支持CMT(Container Management Transaction)的容器运行程序,事务是通过声明定义,在你程序中不需要任何的代码来划分事务。

Hibernate.current_session_context_class参数应该指定,一个org.hibernate.context.CurrentSessionContext的实现类。如果配置参数没有被设置,而是配置了一个org.hibernate.transaction.TransactionManagerLookup被设置,Hibernate将使用org.hibernate.context.JTASessionContext,这里要考虑向后兼容。典型的情况下,这个参数是使用的类的名字。对于Hibernate提供的三个实现类,有对应的三个简短名,“jta”、“thread”、“managed”。

六、Configuration

1.编程配置

一个org.hibernate.cfg.Configuration的实例表示一个应用程序的所有Java类型到数据库类型的映射。org.hibernate.cfg.Configuration是用来建造一个org.hibernate.SessionFactory。被编译的映射是来自所有的XML映射文件。

片断1.

1 Configuration cfg = new Configuration().addResource(“test.hbm.xml”); 

片断2.

2 Configuration cfg = new Configuration().addClass(com.test.class); 

片断3.

3 Configuration cfg = new Configuration().setProperty(“hibernate.dialect”, “org.hibernate.dialect.DB2Dialect”); 

Configuration可以接收的选项:

(1)传递一个java.util.Properties到Configuration.setProperties()。

(2)放一个hibernate.properties文件到类路径的根目录。

(3)设置系统properties,通过java –Dproperty=value。

(4)包含标签指定值在hibernate.cfg.xml文件。

org.hibernate.cfg.Configuration对象是有意作为一个开始时间生成的对象的,一旦SessionFactory被创建,他将被抛弃掉。

七、获取SessionFactory

当org.hibernate.cfg.Configuration解析完所有的映射文件后,应用程序应该获取一个org.hibernate.Session实例的工厂。这个工厂是被应用程序的所有线程共享的。

4 SessionFactory sessionFactory = cfg.buildSessionFactory(); 

Hibernate允许应用程序实例多个SessionFactory。对于使用多个数据库的应用程序是非常有用的。

八、JDBC Connections(Session是对JDBC连接的封装)

通常,你应该使用org.hibernate.SessionFactory来创建或共享JDBC。如果这采用这种方法,是非常简单的。

5 Session session = sessionFactory.openSession(); 

当你的操作需要访问数据库时,一个JDBC连接就会从连接池中被获取。

对于这个工作,我们应该给Hibernate提供一些JDBC连接属性。所有的Hibernate属性名和语义学都被定义在org.hibernate.cfg.Environment。我们现在描述对于JDBC连接配置的一些更重要的设置。

1.如果你设置以下属性,Hibernate将获取或共享连接使用java.sql.DriverManager:

6 hibernate.connection.driver_class  

7  

8 hibernate.connection.url  

9  

10 hibernate.connection.username  

11  

12 hibernate.connection.password  

13  

14 hibernate.connection.pool_size 

Hibernate自己拥有的连接池算法是没有发展的。他是为了你的初始接触使用的,而不是为了你的产品使用的,甚至性能测试时使用。为了更好的性能和稳定性考虑,你应该使用第三方的连接池产品。只需要替换hibernate.connection.pool_size属性的设置用相应连接池的设置。这将关闭Hibernate内部的连接池。例如,可以使用C3P0。

C3P0是一个开源的JDBC连接池,被放置在Hibernate发布文件的lib目录下,随Hibernate一块发行。如果你设置hibernate.c3p0.*属性,Hibernate将会使用org.hibernate.connection.C3P0ConnectionProvider为共享连接。如果你想使用proxool作为连接池,你可以通过查阅hibernat.properties或Hibernate站点获取需要设置的属性名设置。

C3P0配置举例,属性文件片断:

15 hibernate.connection.driver_class=  

16  

17 hibernate.connection.url=  

18  

19 hibernate.connection.username=  

20  

21 hibernate.connection.password=  

22  

23 hibernate.c3p0.min_size=  

24  

25 hibernate.c3p0.max_size=  

26  

27 hibernate.c3p0.timeout=  

28  

29 hibernate.c3p0.max_statements=  

30  

31 hibernate.dialect= 

2.对于在应用服务器内运行的程序,多数情况你应该配置Hibernate通过JNDI找到服务器的javax.sql.DataSource来获取连接。你需要设置以下属性。

32 hibernate.connection.datasource  

33  

34 hibernate.jndi.url  (可选)  

35  

36 hibernate.jndi.class  (可选)  

37  

38 hibernate.connection.username  (可选)  

39  

40 hibernate.connection.password  (可选) 

你可以通过实现org.hibernate.connection.ConnectionProvider来定义自己的获得连接的策略。通过hibernate.connection.provider_class配置使用自己的定义起作用。

 

九、可选配置项

下面介绍的Hibernate属性,有一些是系统级别的。系统级别的属性只能通过-Dproperty=value来设置或在hibernate.properties文件中设置,不能使用上面的方式设置。

1.Hibernate配置项

(1)hibernate.dialect指定方言后,Hibernate可以根据低层数据库自动产生优化过的SQL。取值为org.hibenate.dialect.Dialect的继承类。多数情况下,Hibernate可以根据低层JDBC返回的metadata来判断。

(2)hibernate.show_sql打印所有的SQL语句到控制台,可以通过设置org.hibernate.SQL类的日志策略到DEBUG级,实现同样的效果。取值true|false。

(3)hibernate.format_sql 格式化SQL语句在打印到控制台或写入日志文件时。取值true|false。

(4)hibernate.default_schema 在产生SQL语句时,在表名前加上映射文件给出的表空间(tablespace)或数据库模式(schema)。取值SCHEMA_NAME。

(5)hibernate.default_catalog 在产生SQL语句时,在表名前加上映射文件给出的catalog。取值CATALOG_NAME。

(6)hibernate.session_factory_name  Hibernate创建org.hibernate.SessionFactory实例后后会自动的将这个绑定到JNDI中的名字上。取值jndi/sf。

(7)hibernate.max_fetch_depth 设置对单个表的外连接数最大深度。0是屏蔽默认的外连接设置。推荐设置为0到3之间。

(8)hibernate.default_batch_fetch_size 设置Hibernate批量联合查询的尺度。强烈建议。推荐设置为4、8、16。

(9)hibernate.default_entity_mode 默认的实体表现模式,通过SessionFactory打开的所有的Session。取值,dynamic-map、dom4j、pojo。

(10)hibernate.order_updates 强迫Hibernate通过被更新项的主键值排序SQL更新。这样可以在高并发时,减少事务死锁。取值true|false。

(11)hibernate.generate_statistics 如果设置为true,Hibernate将为性能调整,收集统计信息。取值true|false。

(12)hibernate.use_identifier_rollback 如果设置为true,产生的标识属性将被重置成默认值,当对象被删除后。取值为true|false。

(13)hibernate.use_sql_comments  如果设置为true,Hiberante将为SQL产生注释,这样更利于调试。默认值为false。取值为true|false。

2.Hibernate JDBC和连接的属性

(1)hibernate.jdbc.fetch_size 指定JDBC的查询尺度。通过调用(Statement.setFetchSize())。

(2)hibernate.jdbc.batch_size 指定Hibernate如何使用JDBC2批量更新。取值,推荐5到30。

(3)hibernate.jdbc.batch_versioned_data 设置这个属性为true,JDBC将返回executeBatch执行后正确的行数。打开这个参数,通常是安全的。Hibernate将自动的译码这些数据使用批量DML。默认为false。取值true|false。

(4)hibernate.jdbc.factory_class 选择一个定制的org.hibernate.jdbc.Batcher。所有的应用程序不需要配置这个属性。取值,定义工厂的类名。

(5)hibernate.jdbc.use_scrollable_resultset  Hibernate使用JDBC2的可滚动记录集。当使用用户提供的JDBC连接时,需要设置这个参数。否则,Hibernate使用连接MetaData。取值true|false。

(6)hibernate.jdbc.use_streams_for_binary 当读或写二进制数据或序列化数据从JDBC或到JDBC,使用流。系统级的数据。设置true|false。

(7)hibernate.jdbc.use_get_generated_keys 在插入后,可以使用JDBC3的PreparedStatement.getGeneratedKeys()中的值找回本地产生的键值。要求JDBC3+和JRE1.4+,如果使用Hibernate identifier generator后你的驱动程序有问题,请设置为false。默认情况下,设法连接MetaData来决定。取值,true|false。

(8)hibernate.connection.provider_class 实现了org.hibernate.connection.ConnectionProvider 接口的类的名称,为Hibernate提供连接。

(9)hibernate.connection.isolation 设置JDBC事务隔离的级别。检查java.sql.Connection的定义的常量值,但要注意大多数数据库不支持所有的隔离级别、一些附加的和非标准的隔离级别。取值,1、2、4、8。

(10)hibernate.connection.autocommit  JDBC共享连接的自动提交。(不推荐)取值,true|false。

(11)hibernate.connection.release_mode 指定什么时候,Hibernate应该释放JDBC连接。默认情况下,JDBC是一直存在,只到Session是被明确关闭或断开连接时。对于应用的服务器JTA数据源,你应该使用after_statement强制释放JDBC连接在每个JDBC请求结束后。对于非JTA数据源,通常是在每个事务结束后释放JDBC连接是有意义的。将该值设为auto时,JTA和CMT事务策略时,是选择after_statement方式。JDBC事务策略时,是选择after_transaction。取值,auto(default),on_close,after_statment,after_transaction。

注意:这个设置只影响通过SessionFactory.openSession打开的session。对于通过SessionFactory.getCurrentSession获取的session,CurrentSessionContext实现类的配置是用来控制这些session的连接释放模式。

(12)hibernate.connection. 传递这些属性到DriverManager.getConnection中。

(13)hibernate.jndi. 传递这些属性到JNDI InitialContextFactory。

3.Hibernate Cache 属性

(1)hibernate.cache.provider_class 定制的CacheProvider的类名。

(2)hibernate.cache.use_minimal_puts 花费更多的读操作,来优化二级缓存的最少写操作。这个操作对于集群缓存是非常有用的。在Hibernate3中,对于集群缓存是默认开启该功能的。取值,true|false。

(3)hibernate.cache.use_query_cache 开启查询缓存,个别查询肯定应该开启查询缓存。取值,true|false。

(4)hibernate.cache.use_second_level_cache 也许过去习惯于完全屏蔽掉二级缓存,默认是开启,对于指定CacheProvider实现类的情况。取值,true|false。

(5)hibernate.cache.query_cache_factory  实现QueryCache接口的类名,默认是内置的StandardQueryCache。

(6)hibernate.cache.region_prefix 对于使用二级缓存区域名的前缀。

(7)hibernate.cache.use_structured_entries 强迫Hibernate在存储数据到二级缓存时,使用更人性化的格式。取值,true|false。

4.Hibernate事务属性

(1)hibernate.transaction.transaction_class  使用Hibernate事务APIs的TransactionFactory的类名。默认是JDBCTransactionFactory。

(2)jta.UserTransaction  JTATransactionFactory使用JNDI名字从应用服务器中获取JTA UserTransaction。取值,jndi/ut。

(3)hibernate.transaction.manager_lookup_class 是一个TransactionManagerLookup实现类的类名。当JVM级别的缓存开启时或在JTA环境中使用hilo generator时,要求指定该值。

(4)hibernate.transaction.flush_before_completion 如果设为true,session将在事务完成阶段之前,自动将缓存区的值推入到数据库中。内置和自动session上下文管理是被优先选用的。取值,true|false。

(5)hibernate.transaction.auto_close_session 如果设为true,session将在事务完成之后,自动的关闭session。内置和自动session上下文管理是被优先选用的。取值,true|false。

5.Miscellaneous properties 各种混合的属性

(1)hibernate.current_session_context_class 提供一个对于当前session生命周期的策略。取值,jta、thread、managed、定制类名。

(2)hibernate.query.factory_class 选择HSQL的解析实现类。取值,org.hibernate.hsql.ast.ASTQueryTranslatorFactory和org.hibernate.hsql.classic.ClassicQueryTranslatorFactory。

(3)hibernate.query.subsitutions Hibernate中标记符到SQL中标记符的映射。举例说,可以是函数名或普通字符串名。取值,如hsqLiteral=SQL_LITERAL,hqlFunction=SQLFUN。

(4)hibernate.hbm2ddl.auto 当SessionFactory被创建时,自动的验证或输出模式DDL(也就建表语句)到数据库中。也就是说,自动的验证数据库表结构或先删除再重新建立,或在原表结构上更新数据表结构。当将值置为create-drop时,在SessionFactory被清除时,将删除数据库中表结构。取值,validate、create、update、create-drop。

(5)hibernate.cglib.use_reflection_optimizer 用CGLIB代替运行期的reflection(系统级属性)。在有故障时,反射是非常有用的,注意Hibernate总是需要CGLIB,甚至在你关闭优化后。你不可以设置这个属性在hibernate.cfg.xml文件中。

 

 

  • 09:20
  • 浏览 (282)
  • 评论 (1)
  • 分类: Hibernate
2009-12-03缩略显示

Hibernate配置项

Xml代码
  1.   
  2.  id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
  3.      name="dataSource" ref="dataSource" />  
  4.      name="packagesToScan">  
  5.           
  6.               
  7.           
  8.       
  9.      name="hibernateProperties">  
  10.           
  11.              key="hibernate.cache.provider_class">${hibernate.cache.provider_class}  
  12.              key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}  
  13.              key="hibernate.dialect">${hibernate.dialect}  
  14.              key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}  
  15.              key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}  
  16.              key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}  
  17.              key="hibernate.show_sql">${hibernate.show_sql}  
  18.              key="hibernate.format_sql">${hibernate.format_sql}  
  19.              key="hibernate.show_sql">${hibernate.use_sql_comments}  
  20.              key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.cache.provider_configuration_file_resource_path}  
  21.           
  22.       
  23.   

 

hibernate.properties

#Oracle方言
# hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
# hibernate.dialect=org.hibernate.dialect.SQLServerDialect
#hibernate方言
hibernate.dialect=org.hibernate.dialect.SQLServerDialect


#是否启用二级缓存,
hibernate.cache.use_query_cache=true
#二级缓存class
# hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
# hibernate.cache.provider_class=org.hibernate.cache.SingletonEhCacheProvider
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
#二级缓存配置文件
hibernate.cache.provider_configuration_file_resource_path=/cache/ehcache.xml

#是否同步数据库结构(自动创建|更新|验证数据库表结构)
#none: 不做任何操作
#create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行。会导致数据库表数据丢失。
#create-drop: 每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
#update:第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
#validate:验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
hibernate.hbm2ddl.auto=none


#关于hibernate.jdbc.fetch_size与hibernate.jdbc.batch_size的设置,可能会将严重影响Hibernate的CRUD性能。
#设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数。
#Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。
#MySQL就支持Fetch Size特性
hibernate.jdbc.fetch_size=20
#设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小。
#Batch Size越大,批量操作的向数据库发送sql的次数越少,速度就越快。
hibernate.jdbc.batch_size=50

#设置外连接抓取树的最大深度取值. 建议设置为0到3之间
#hibernate.max_fetch_depth

#是否显示最终执行的SQL(开发环境)
hibernate.show_sql=false
#格式化显示的SQL
hibernate.format_sql=false
#如果设置为true,Hiberante将为SQL产生注释,这样更利于调试。默认值为false。取值为true|false。
hibernate.use_sql_comments=false

 

 

 

 

 

(附录) Hibernate配置项:

 

1.Hibernate配置项

(1)hibernate.dialect指定方言后,Hibernate可以根据低层数据库自动产生优化过的SQL。取值为org.hibenate.dialect.Dialect的继承类。多数情况下,Hibernate可以根据低层JDBC返回的metadata来判断。

(2)hibernate.show_sql打印所有的SQL语句到控制台,可以通过设置org.hibernate.SQL类的日志策略到DEBUG级,实现同样的效果。取值true|false。

(3)hibernate.format_sql 格式化SQL语句在打印到控制台或写入日志文件时。取值true|false。

(4)hibernate.default_schema 在产生SQL语句时,在表名前加上映射文件给出的表空间(tablespace)或数据库模式(schema)。取值SCHEMA_NAME。

(5)hibernate.default_catalog 在产生SQL语句时,在表名前加上映射文件给出的catalog。取值CATALOG_NAME。

(6)hibernate.session_factory_name  Hibernate创建org.hibernate.SessionFactory实例后后会自动的将这个绑定到JNDI中的名字上。取值jndi/sf。

(7)hibernate.max_fetch_depth 设置对单个表的外连接数最大深度。0是屏蔽默认的外连接设置。推荐设置为0到3之间。

(8)hibernate.default_batch_fetch_size 设置Hibernate批量联合查询的尺度。强烈建议。推荐设置为4、8、16。

(9)hibernate.default_entity_mode 默认的实体表现模式,通过SessionFactory打开的所有的Session。取值,dynamic-map、dom4j、pojo。

(10)hibernate.order_updates 强迫Hibernate通过被更新项的主键值排序SQL更新。这样可以在高并发时,减少事务死锁。取值true|false。

(11)hibernate.generate_statistics 如果设置为true,Hibernate将为性能调整,收集统计信息。取值true|false。

(12)hibernate.use_identifier_rollback 如果设置为true,产生的标识属性将被重置成默认值,当对象被删除后。取值为true|false。

(13)hibernate.use_sql_comments 如果设置为true,Hiberante将为SQL产生注释,这样更利于调试。默认值为false。取值为true|false。

2.Hibernate JDBC和连接的属性

(1)hibernate.jdbc.fetch_size 指定JDBC的查询尺度。通过调用(Statement.setFetchSize())。

(2)hibernate.jdbc.batch_size 指定Hibernate如何使用JDBC2批量更新。取值,推荐5到30。

(3)hibernate.jdbc.batch_versioned_data 设置这个属性为true,JDBC将返回executeBatch执行后正确的行数。打开这个参数,通常是安全的。Hibernate将自动的译码这些数据使用批量DML。默认为false。取值true|false。

(4)hibernate.jdbc.factory_class 选择一个定制的org.hibernate.jdbc.Batcher。所有的应用程序不需要配置这个属性。取值,定义工厂的类名。

(5)hibernate.jdbc.use_scrollable_resultset  Hibernate使用JDBC2的可滚动记录集。当使用用户提供的JDBC连接时,需要设置这个参数。否则,Hibernate使用连接MetaData。取值true|false。

(6)hibernate.jdbc.use_streams_for_binary 当读或写二进制数据或序列化数据从JDBC或到JDBC,使用流。系统级的数据。设置true|false。

(7)hibernate.jdbc.use_get_generated_keys 在插入后,可以使用JDBC3的PreparedStatement.getGeneratedKeys()中的值找回本地产生的键值。要求JDBC3+和JRE1.4+,如果使用Hibernate identifier generator后你的驱动程序有问题,请设置为false。默认情况下,设法连接MetaData来决定。取值,true|false。

(8)hibernate.connection.provider_class 实现了org.hibernate.connection.ConnectionProvider 接口的类的名称,为Hibernate提供连接。

(9)hibernate.connection.isolation 设置JDBC事务隔离的级别。检查java.sql.Connection的定义的常量值,但要注意大多数数据库不支持所有的隔离级别、一些附加的和非标准的隔离级别。取值,1、2、4、8。

(10)hibernate.connection.autocommit  JDBC共享连接的自动提交。(不推荐)取值,true|false。

(11)hibernate.connection.release_mode 指定什么时候,Hibernate应该释放JDBC连接。默认情况下,JDBC是一直存在,只到Session是被明确关闭或断开连接时。对于应用的服务器JTA数据源,你应该使用after_statement强制释放JDBC连接在每个JDBC请求结束后。对于非JTA数据源,通常是在每个事务结束后释放JDBC连接是有意义的。将该值设为auto时,JTA和CMT事务策略时,是选择after_statement方式。JDBC事务策略时,是选择after_transaction。取值,auto(default),on_close,after_statment,after_transaction。

注意:这个设置只影响通过SessionFactory.openSession打开的session。对于通过SessionFactory.getCurrentSession获取的session,CurrentSessionContext实现类的配置是用来控制这些session的连接释放模式。

(12)hibernate.connection. 传递这些属性到DriverManager.getConnection中。

(13)hibernate.jndi. 传递这些属性到JNDI InitialContextFactory。

3.Hibernate Cache 属性

(1)hibernate.cache.provider_class 定制的CacheProvider的类名。

(2)hibernate.cache.use_minimal_puts 花费更多的读操作,来优化二级缓存的最少写操作。这个操作对于集群缓存是非常有用的。在Hibernate3中,对于集群缓存是默认开启该功能的。取值,true|false。

(3)hibernate.cache.use_query_cache 开启查询缓存,个别查询肯定应该开启查询缓存。取值,true|false。

(4)hibernate.cache.use_second_level_cache 也许过去习惯于完全屏蔽掉二级缓存,默认是开启,对于指定CacheProvider实现类的情况。取值,true|false。

(5)hibernate.cache.query_cache_factory  实现QueryCache接口的类名,默认是内置的StandardQueryCache。

(6)hibernate.cache.region_prefix 对于使用二级缓存区域名的前缀。

(7)hibernate.cache.use_structured_entries 强迫Hibernate在存储数据到二级缓存时,使用更人性化的格式。取值,true|false。

4.Hibernate事务属性

(1)hibernate.transaction.transaction_class  使用Hibernate事务APIs的TransactionFactory的类名。默认是JDBCTransactionFactory。

(2)jta.UserTransaction  JTATransactionFactory使用JNDI名字从应用服务器中获取JTA UserTransaction。取值,jndi/ut。

(3)hibernate.transaction.manager_lookup_class 是一个TransactionManagerLookup实现类的类名。当JVM级别的缓存开启时或在JTA环境中使用hilo generator时,要求指定该值。

(4)hibernate.transaction.flush_before_completion 如果设为true,session将在事务完成阶段之前,自动将缓存区的值推入到数据库中。内置和自动session上下文管理是被优先选用的。取值,true|false。

(5)hibernate.transaction.auto_close_session 如果设为true,session将在事务完成之后,自动的关闭session。内置和自动session上下文管理是被优先选用的。取值,true|false。

5.Miscellaneous properties 各种混合的属性

(1)hibernate.current_session_context_class 提供一个对于当前session生命周期的策略。取值,jta、thread、managed、定制类名。

(2)hibernate.query.factory_class 选择HSQL的解析实现类。取值,org.hibernate.hsql.ast.ASTQueryTranslatorFactory和org.hibernate.hsql.classic.ClassicQueryTranslatorFactory。

(3)hibernate.query.subsitutions Hibernate中标记符到SQL中标记符的映射。举例说,可以是函数名或普通字符串名。取值,如hsqLiteral=SQL_LITERAL,hqlFunction=SQLFUN。

(4)hibernate.hbm2ddl.auto 当SessionFactory被创建时,自动的验证或输出模式DDL(也就建表语句)到数据库中。也就是说,自动的验证数据库表结构或先删除再重新建立,或在原表结构上更新数据表结构。当将值置为create-drop时,在SessionFactory被清除时,将删除数据库中表结构。取值,validate、create、update、create-drop。

(5)hibernate.cglib.use_reflection_optimizer 用CGLIB代替运行期的reflection(系统级属性)。在有故障时,反射是非常有用的,注意Hibernate总是需要CGLIB,甚至在你关闭优化后。你不可以设置这个属性在hibernate.cfg.xml文件中。

  

 

 

 

 

 

 

 

 

 

  • 09:12
  • 浏览 (461)
  • 评论 (2)
  • 分类: Hibernate
2009-12-01缩略显示

SVN版本控制器的安装和配置

文章来源:Subversion中文站

 

      如何快速建立Subversion服务器,并且在项目中使用起来,这是大家最关心的问题,与CVS相比,Subversion有更多的选择,也更加的容易,几个命令就可以建立一套服务器环境,可以使用起来,这里配套有动画教程
本文是使用Subversion最快速的教程,在最短的时间里帮助您建立起一套可用的服务器环境,只需略加调整就可以应用到实际项目当中。 
      本教程分为以下几个部门,不仅仅是快速入门,最后我们还有一些高级功能的说明,为了说明简单,教程是在windows下使用的方式,以方便资源有限的项目使用,对于UNIX环境下,区别并不大。

 

1,软件下载

下载Subversion服务器程序。

官方网站的下载二进制安装文件,来到二进制包下载部分,找到 Windows NT, 2000, XP and 2003部分,然后选择" this directory ",这样我们可以看到许多下载的内容,目前可以下载 svn-1.4.0-setup.exe

下载Subversion的Windows客户端TortoiseSVN。

TortoiseSVN是扩展Windows Shell的一套工具,可以看作Windows资源管理器的插件,安装之后Windows就可以识别Subversion的工作目录。
官方网站是TortoiseSVN ,下载方式和前面的svn服务器类似,在Download页面的我们可以选择下载的版本,目前的最高稳定版本的安装文件为TortoiseSVN-1.4.0.7501-win32-svn-1.4.0.msi。

2,服务器和客户端安装

服务器安装,直接运行svn-1.4.0-setup.exe ,根据提示安装即可,这样我们就有了一套服务器可以运行的环境。

安装TortoiseSVN,同样直接运行TortoiseSVN-1.4.0.7501-win32-svn-1.4.0.msi按 照提示安装即可,不过最后完成后会提示是否重启,其实重启只是使svn工作拷贝在windows中的特殊样式生效,与所有的实际功能无关,这里为了立刻看 到好的效果,还是重新启动机器。若是不习惯英文还可以选择安装客户端语言汉化包“LanguagePack-1.4.5.10425-win32- zh_CN.exe”(也需下载),安装后默认还是英文,需要在客户端工具中设置一下。

此外,在编译器中也可以使用SVN插件来代替客户端工具,使开发起来更加方便。详细介绍请见Eclipse中SVN版本控制插件的安装和使用

3,建立版本库(Repository)

运行Subversion服务器需要首先要建立一个版本库(Repository),可以看作服务器上存放数据的数据库,在安装了Subversion服务器之后,可以直接运行,如:

svnadmin create E:\svndemo\repository

就会在目录E:\svndemo\repository下创建一个版本库。

我们也可以使用TortoiseSVN图形化的完成这一步:
在目录E:\svndemo\repository下"右键->TortoiseSVN->Create Repository here...“, 然后可以选择版本库模式, 这里使用默认即可, 然后就创建了一系列目录和文件。


4,配置用户和权限

svn的权限管理涉及到一下文件:
passwd文件   --   /conf目录下   用于存放本svn库的用户名和密码,用 = 分割,左边是用户名,右边是密码(明文)。
authz   --   /conf目录下   用于存放本svn库的访问授权信息。
svnserve.conf   -- /conf目录下   用于存放本svn库的全局访问控制信息。

来到E:\svndemo\repository\conf目录,修改svnserve.conf:
# [general]
# password-db = passwd
改为:
[general]
password-db = passwd 然后修改同目录的passwd文件(设置用户密码),去掉下面三行的注释再加两个用户:
# [users]
# harry = harryssecret
# sally = sallyssecret
最后变成:
[users]
harry = harryssecret
sally = sallyssecret
svnadmin = admin
zgz = zgz0809
最后修改同目录的authz文件,它定义了两部分的内容:
1,对组成员的定义,
2,对目录的授权定义,
可以针对一个单一用户授权,也可以针对在[groups]里面定义的一个组授权,还可以用*通配符来对所有的用户授权,
授权的选项有:只读访问('r'),读写访问('rw'),或者无权防问('').
authz文件中可以对任意多个目录进行权限控制,一下是一个例子:

[groups]
harry_and_sally = harry,sally
#设定权限组

[/]
svnadmin = rw

[/truck]
zgz = rw
harry = rw
sally = r
* = r

[/sanguo]
zgz = rw
harry = r
sally = rw
* = r

[/ts]
@harry_and_sally = rw
# 以@为键值意味着对前面定义的组进行授权
* = r

# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r

用户svnadmin权限最大,他可以进行根目录(注意:是服务器目录svn://localhost/,下边会介绍的)下所有文件(包括子目录下的文件)的读写操作,而/truck,/sanguo,/ts是在服务器的根目录下创建的三个子目录。
用户zgz 和harry对 /truck具有读写权限,sally 只有读的权限。
用户zgz 和sally对 /sanguo具有读写权限,harry 只有读的权限。
用户harry 和sally对 /ts具有读写权限,zgz只有读的权限。(* = r 表示所有用户都具有读的权限,当然zgz也就自然具有了。注意这里 @harry_and_sally = rw 表示给harry_and_sally组所有用户授权,该组在上边[groups]标签中已定义)

注意:如果用户对一个目录具有某种权限,那么他对其子目录也有同样的权限(例如:svnadmin),所以在授权时要特别注意,尽量只付给满足用户需要的最小的权限。

 

5,运行独立服务器

在任意目录下运行:
svnserve -d -r E:\svndemo\repository 我们的服务器程序就已经启动了。注意不要关闭命令行窗口,关闭窗口也会把svnserve停止。为了方便,可以把svnserve作为服务,在2000下控制台窗口可以运行,创建服务命令:

sc.exe create SVNService binpath= "D:\Subversion\bin\svnserve.exe --service -r E:\svndemo\repository" depend= tcpip
如果加错了可以用:sc delete "SVNService" 命令删除服务。
加好后可以在控制面板的服务选项中找到它,把它启动类型设为手动,然后启动一下看看有没有问题。


注意:

1."D:\Subversion"是SVN服务器端的安装路径,"E:\svndemo\repository"是版本库的路径,视具体情况而定。
2. 等号前无空格后有空格。
3. 应使用参数“--service”而不是“-d”,参数前面的横线不是一个是两个。
4. binpath内套的路径如果包含空格,也需要使用双引号,此时需要使用转义符表示内部的引号(\")。
5.使用“SVNService.exe”将SVN作为Window服务运行(Subversion1.4之前版本也可使用)
SVNService.exe -install -d -r E:\svndemo\repository


6,初始化导入

来到我们想要导入的项目根目录,在这个例子里是E:\svndemo\wc1,目录下有一个readme.txt文件:


右键->TortoiseSVN->Import...
URL of repository输入“svn://localhost/” ,如果服务安装在其他机器则将localhost改换为目标机器的IP地址“svn://10.8.6.87/”。
ok
完成之后目录没有任何变化,如果没有报错,数据就已经全部导入到了我们刚才定义的版本库中。

需要注意的是,这一步操作可以完全在另一台安装了TortoiseSVN的主机上进行。例如运行svnserve的主机的IP是 10.8.6.87,则URL部分输入的内容就是“svn://10.8.6.87/”,一般为了便于管理不会导入到服务的根目录下,而是导入到工程的子 目录,如/truck,/sanguo,/ts。导入的URL就添svn://localhost/truck。


7,基本客户端操作

取出版本库到一个工作拷贝:
来到任意空目录下,在本例中是E:\svndemo\wc1,运行右键->Checkout,在URL of repository中输入svn://localhost/,这样我们就得到了一份工作拷贝。
在工作拷贝中作出修改并提交:
打开readme.txt,作出修改,然后右键->Commit...,这样我们就把修改提交到了版本库,我们可以运行。

察看所作的修改:
readme.txt上右键->TortoiseSVN->Show Log,这样我们就可以看到我们对这个文件所有的提交。在版本1上右键->Compare with working copy,我们可以比较工作拷贝的文件和版本1的区别。功能挺强大,具体使用不做详解。

 

相关资源
Subversion http://subversion.tigris.org/
TortoiseSVN http://tortoisesvn.net/downloads http://tortoisesvn.tigris.org/
Svn1ClickSetup http://svn1clicksetup.tigris.org/
Subclipse http://subclipse.tigris.org/
Subversion中文站 http://www.subversion.org.cn/

  • 12:50
  • 浏览 (221)
  • 评论 (0)
2009-11-25缩略显示

Apache commons简介

Apache Commons 是一个非常有用的工具包,解决各种实际的通用问题,下面是一个简述表。
( 详细信息访问http://commons.apache.org/index.html )

 

BeanUtils
Commons-BeanUtils 提供对 Java 反射和自省API的包装。

 

Betwixt
Betwixt提供将 JavaBean 映射至 XML 文档,以及相反映射的服务。

 

Chain
Chain 提供实现组织复杂的处理流程的“责任链模式”。

 

CLI
CLI 提供针对命令行参数,选项,选项组,强制选项等的简单API。

 

Codec
Codec 包含一些通用的编码解码算法。包括一些语音编码器, Hex, Base64, 以及URL encoder。

 

Collections
Commons-Collections 提供一个类包来扩展和增加标准的 Java Collection框架。

 

Configuration
Commons-Configuration 工具对各种各式的配置和参考文件提供读取帮助。

 

Daemon
一种 unix-daemon-like java 代码的替代机制。

 

DBCP
Commons-DBCP 提供数据库连接池服务。

 

DbUtils
DbUtils 是一个 JDBC helper 类库,完成数据库任务的简单的资源清除代码。

 

Digester
Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件。

 

Discovery
Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。

 

EL
Commons-EL 提供在JSP2.0规范中定义的EL表达式的解释器。

 

FileUpload
FileUpload 使得在你可以在应用和Servlet中容易的加入强大和高性能的文件上传能力。

 

HttpClient
Commons-HttpClient 提供了可以工作于HTTP协议客户端的一个框架。

 

IO
IO 是一个 I/O 工具集。

 

Jelly
Jelly是一个基于 XML 的脚本和处理引擎。 Jelly 借鉴了 JSP 定指标签,Velocity, Cocoon和Xdoclet中的脚本引擎的许多优点。Jelly 可以用在命令行, Ant 或者 Servlet之中。

 

Jexl
Jexl是一个表达式语言,通过借鉴来自于Velocity的经验扩展了JSTL定义的表达式语言。

 

JXPath
Commons-JXPath 提供了使用Xpath语法操纵符合Java类命名规范的 JavaBeans的工具。也支持 maps, DOM 和其他对象模型。

 

Lang
Commons-Lang 提供了许多许多通用的工具类集,提供了一些java.lang中类的扩展功能。

 

Latka
Commons-Latka 是一个HTTP 功能测试包,用于自动化的QA,验收和衰减测试。

 

Launcher
Launcher 组件是一个交叉平台的Java 应用载入器。 Commons-launcher 消除了需要批处理或者Shell脚本来载入Java 类。.原始的 Java 类来自于Jakarta Tomcat 4.0 项目。

 

Logging
Commons-Logging 是一个各种 logging API实现的包裹类。

 

Math
Math 是一个轻量的,自包含的数学和统计组件,解决了许多非常通用但没有及时出现在Java标准语言中的实践问题。

 

Modeler
Commons-Modeler 提供了建模兼容JMX规范的 Mbean的机制。

 

Net
Net 是一个网络工具集,基于 NetComponents 代码,包括 FTP 客户端等等。

 

Pool
Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实现。

 

Primitives
Commons-Primitives提供了一个更小,更快和更易使用的对Java基本类型的支持。当前主要是针对基本类型的 collection。

 

Validator
The commons-validator提供了一个简单的,可扩展的框架来在一个XML文件中定义校验器 (校验方法)和校验规则。支持校验规则的和错误消息的国际化。

  • 15:32
  • 浏览 (110)
  • 评论 (0)
  • 分类: Java
2009-11-22缩略显示

Firefox和IE6垂直居中

关键字: css Html代码
  1.   
  2.       
  3.          style="display: table-cell; vertical-align: middle; height: 200px; border: 1px solid red;">  
  4.             

    垂直居中,Firefox only

      
  5.             

    垂直居中,Firefox only

      
  6.             

    垂直居中,Firefox only

      
  7.         
  
  •          style="border: 1px solid red; height: 200px; position: relative;">  
  •               style="position: absolute; top: 50%;">  
  •                   style="position: relative; top: -50%;">  
  •                      

    垂直居中,IE6 only

      
  •                      

    垂直居中,IE6 only

      
  •                      

    垂直居中,IE6 only

      
  •                  
  •   
  •              
  •   
  •         
  •   
  •          style="border: 1px solid red; height: 200px; position: relative; display: table-cell; vertical-align: middle;">  
  •               style="position: static !important; position: absolute; top: 50%;">  
  •                   style="position: relative; top: -50%;">  
  •                      

    垂直居中,Firefox IE6 only

      
  •                      

    垂直居中,Firefox IE6 only

      
  •                      

    垂直居中,Firefox IE6 only

      
  •