1.Hibernate优化
1.1配置C3P0连接池
注意:要先导入c3p0的jar包(c3p0-xxx.jar)
<!-- 设置连接池提供者 C3P0-->
<propertyname="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<propertyname="hibernate.c3p0.max_size">20</property><!--最大连接数 -->
<propertyname="hibernate.c3p0.min_size">5</property><!--最小连接数 -->
<propertyname="hibernate.c3p0.max_statements">110</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<propertyname="hibernate.c3p0.timeout">5000</property>
<!--每3000秒检查所有连接池中的空闲连接以秒为单位-->
<propertyname="hibernate.c3p0.idle_test_period">3000</property>
<propertyname="hibernate.c3p0.acquire_increment">5</property><!--每次请求多少连接 -->
1.2事务隔离级别
SQL 标准定义了隔离级别,但并不是SQL数据库独有.JTA也定义了同样的隔
离级别.级别越高,成本越高。
READ_UNCOMMITED:允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读。
REPEATABLE_READ:允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生。
REPEATABLE_READ:对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生。Mysql数据库默认的隔离级别。
SERIALIZABLE:完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。
事务的隔离isolation。
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
MySQL的默认隔离级别是4,可防止脏、不可重复读,但幻读仍可能发生。
由轻到重:脏读----不可重复读----幻读
不遵守并发性时会导致脏读,不可重复读,幻读。
脏读:偷窥到未真正插入的数据。(两条线程)
不可重复读:在一个事务(一条线程中)中前后读到的数据不一致,内容不同
幻读(虚读):条数变化
即使设置了隔离级别,也不可能改变数据库或服务器的内部隔离级别。只会影响。
Hibernate事务隔离级别配置:
每个数据库连接都有默认的隔离级别,通常是读已提交或可重复读.可以通过数据库配置设置,也可在应用程序中设置.例如Hibernate:
hibernate.connection.isolation = 4
1—Read uncommitted isolation
2—Read committed isolation
4—Repeatableread isolation
8—Serializable isolation
注意:Hibernate不可能改变在受管环境下由应用服务器提供的数据 库连接的隔离级别,只能通过改变应用服务器配置的方式来改变。
<!-- 设置事务的隔离级别,可以避免数据脏读和不可重复读 -->
<propertyname="hibernate.connection.isolation">4</property>
1.3管理session
Hibernate 3 自身提供了三种管理 Session 对象的方法
Session对象的生命周期与本地线程绑定
Session 对象的生命周期与 JTA 事务绑定
Hibernate 委托程序管理 Session 对象的生命周期
在 Hibernate 的配置文件中, hibernate.current_session_context_class 属性用于指定 Session 管理方式, 可选值包括
thread:Session 对象的生命周期与本地线程绑定
jta: Session 对象的生命周期与 JTA 事务绑定
managed: Hibernate 委托程序来管理 Session 对象的生命周期
<!-- 让session和当前线程绑定一起,直至线程销毁 -->
<propertyname="current_session_context_class">thread</property>
配置后,不再是调用sessionFactory.openSession().而是调用sessionFactory. getCurrentSession().获取session对象.从当前的线程提取session,
当前线程如果存在session对象,取出直接使用。
当前线程如果不存在session对象,获取一个新的session对象和当前的线程绑定。
1.4管理sessionFactory二级缓存
session一级缓存,默认开启
sessionFactory二级缓存,默认不开启
开启二级缓存:293行(缓存提供者)
开启---告诉缓存哪个类
<!-- 开始SessionFactory二级缓存,默认关闭,并配置使用什么作为缓存容器
要加jar包oscache-2.1.jar和commons-logging-1.1.1.jar-->
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
二级缓存对get和load方法一样有效。
总是变化的类不建议放到二级缓存中,不变化或不经常变化的类建议放到二级缓存中。
list()默认不使用二级缓存,要设置
uniqueResult默认不使用二级缓存,要代码设置
query.setCacheable(true);//将返回的对放到查询缓存中xxx.setCacheable(true)
查询缓存(默认不开启,false),专用于缓存HQL查询返回的对象。
key:hql
value:对象
<!-- 开启查询缓存,执行HQL返回的对象会被缓存 -->
<propertyname="hibernate.cache.use_query_cache">true</property>
类缓存:默认不使用二级缓存,要配置
集合缓存:默认不使用二级缓存,要配置
<class-cache>
<collection-cache>
一级缓存和二级缓存之前会相互沟通的。会同步更新(即更新一级缓存时,框架会更新与之相关的二级缓存,但usage至少要为read-write)。
<!-- 设置Customer类的对象可以被放到二级缓存中全类名 -->
<class-cacheusage="read-write"class="com.maple.shexercise.domain.Customer"/>
<!-- 设置Order类的对象可以被放到二级缓存中 -->
<class-cacheusage="read-write"class="com.maple.shexercise.domain.Order"/>
<!-- 设置某个类的集合属性可以被缓存,要全路径,同时集合元素必须要设置可以被缓存-->
<collection-cacheusage="read-write"collection="com.maple.shexercise.domain.Customer.orderSet"/>
完整Xxx.hbm.xml文件:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.url">jdbc:mysql://localhost:3306/shexercise</property>
<propertyname="hibernate.connection.username">root</property>
<propertyname="hibernate.connection.password">admin</property>
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 设置连接池提供者 C3P0-->
<propertyname="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<propertyname="hibernate.c3p0.max_size">20</property><!--最大连接数 -->
<propertyname="hibernate.c3p0.min_size">5</property><!--最小连接数 -->
<propertyname="hibernate.c3p0.max_statements">110</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除-->
<propertyname="hibernate.c3p0.timeout">5000</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<propertyname="hibernate.c3p0.idle_test_period">3000</property>
<propertyname="hibernate.c3p0.acquire_increment">5</property><!--每次请求多少连接 -->
<propertyname="hibernate.show_sql">true</property>
<!-- 设置由框架自动生成表 每次都创建新的表-->
<propertyname="hibernate.hbm2ddl.auto">update</property>
<!-- 让session和当前线程绑定一起,直至线程销毁 -->
<propertyname="current_session_context_class">thread</property>
<!-- 设置事务提交后自动关闭session,不用在代码中手动关闭 -->
<propertyname="hibernate.transaction.auto_close_session">true</property>
<!-- 设置事务的隔离级别,可以避免数据脏读和不可重复读 -->
<propertyname="hibernate.connection.isolation">4</property>
<!-- 开始SessionFactory二级缓存,默认关闭,并配置使用什么作为缓存容器
要加jar包oscache-2.1.jar和commons-logging-1.1.1.jar-->
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
<!-- 开启查询缓存,执行HQL返回的对象会被缓存 -->
<propertyname="hibernate.cache.use_query_cache">true</property>
<mappingresource="com/maple/shexercise/domain/Customer.hbm.xml"/>
<mappingresource="com/maple/shexercise/domain/Order.hbm.xml"/>
<!-- 设置Customer类的对象可以被放到二级缓存中 全类名 -->
<class-cacheusage="read-write"class="com.maple.shexercise.domain.Customer"/>
<!-- 设置Order类的对象可以被放到二级缓存中 -->
<class-cacheusage="read-write"class="com.maple.shexercise.domain.Order"/>
<!-- 设置某个类的集合属性可以被缓存,要全路径,同时集合元素必须要设置可以被缓存-->
<collection-cacheusage="read-write"collection="com.maple.shexercise.domain.Customer.orderSet"/>
</session-factory>
</hibernate-configuration>