1、导入c3p0的jar包
hibernate-release-4.3.11.Final/lib/optional/c3p0/*.jar
2、加入配置
- hibernate.c3p0.max_size: 数据库连接池的最大连接数
- hibernate.c3p0.min_size: 数据库连接池的最小连接数
- hibernate.c3p0.timeout: 数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁
- hibernate.c3p0.max_statements: 缓存 Statement 对象的数量
- hibernate.c3p0.idle_test_period: 表示连接池检测线程多长时间检测一次池内的所有链接对象是否超时. 连接池本身不会把自己从连接池中移除,而是专门有一个线程按照一定的时间间隔来做这件事,这个线程通过比较连接对象最后一次被使用时间和当前时间的时间差来和 timeout 做对比,进而决定是否销毁这个连接对象。
- hibernate.c3p0.acquire_increment: 当数据库连接池中的连接耗尽时, 同一时刻获取多少个数据库连接
<!--配置c3p0数据源-->
<!--数据库连接池的最大连接数-->
<property name="hibernate.c3p0.max_size">10</property>
<!--数据库连接池的最小连接数-->
<property name="hibernate.c3p0.min_size">5</property>
<!--当数据库连接池中的连接耗尽时,同一时刻获取多少个数据库连接-->
<property name="hibernate.c3p0.acquire_increment">2</property>
<!--表示连接池检测线程多长时间检测一次池内的所有连接对象是否超时-->
<property name="hibernate.c3p0.idle_test_period">2000</property>
<!--数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁-->
<property name="hibernate.c3p0.timeout">2000</property>
<!--缓存Statement对象的数量-->
<property name="hibernate.c3p0.max_statements">2</property>
========================================================
- hibernate.jdbc.fetch_size:实质是调用
Statement.setFetchSize()
方法设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数
。例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会 1 次性把1万条取出来的,而只会取出 fetchSize 条数,当结果集遍历完了这些记录以后,再去数据库取 fetchSize 条数据。因此大大节省了无谓的内存消耗。Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。Oracle数据库的JDBC驱动默认的Fetch Size = 10,是一个保守的设定,根据测试,当Fetch Size=50时,性能会提升1倍之多,当 fetchSize=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持 - hibernate.jdbc.batch_size:
设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小
,类似于设置缓冲区大小的意思。batchSize 越大,批量操作时向数据库发送sql的次数越少,速度就越快。
测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!Oracle数据库 batchSize=30 的时候比较合适。
<!--设定jdbc的Statement读取数据的时候每次从数据库中取出的记录条数。MySQL不支持-->
<property name="hibernate.jdbc.fetch_size">100</property>
<!--设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小-->
<property name="hibernate.jdbc.batch_size">50</property>
代码测试:
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置数据库信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 配置hibernate信息 -->
<!--执行操作时是否在控制台打印sql-->
<property name="hibernate.show_sql">true</property>
<!--是否对sql进行格式化-->
<property name="hibernare.format_sql">true</property>
<!--指定自动生成数据表的策略-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 设置hibernate所使用的数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--删除对象后,使其OID置为null-->
<property name="hibernate.use_identifier_rollback">true</property>
<!--配置c3p0数据源-->
<!--数据库连接池的最大连接数-->
<property name="hibernate.c3p0.max_size">10</property>
<!--数据库连接池的最小连接数-->
<property name="hibernate.c3p0.min_size">5</property>
<!--当数据库连接池中的连接耗尽时,同一时刻获取多少个数据库连接-->
<property name="hibernate.c3p0.acquire_increment">2</property>
<!--表示连接池检测线程多长时间检测一次池内的所有连接对象是否超时-->
<property name="hibernate.c3p0.idle_test_period">2000</property>
<!--数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁-->
<property name="hibernate.c3p0.timeout">2000</property>
<!--缓存Statement对象的数量-->
<property name="hibernate.c3p0.max_statements">2</property>
<!--设定JDBC的Statement 读取数据的时候每次从数据库中取出来的记录条数-->
<property name="hibernate.jdbc.fetch_size">100</property>
<!--设定对数据库进行批量操作(删除、更新、插入)的时候的批次大小-->
<property name="hibernate.jdbc.batch_size">10</property>
<!-- 指定关联的hibernate映射文件 -->
<mapping resource="com/zm/c3p0/news.hbm.xml"/>
</session-factory>
</hibernate-configuration>
news.hbm.xml:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.zm.c3p0.News" table="news" schema="hibernate_db" select-before-update="true">
<id name="id" type="java.lang.Integer">
<column name="id" sql-type="int(11)"/>
<!-- 主键的生成方式 -->
<generator class="native"></generator>
</id>
<property name="title" type="java.lang.String">
<column name="title" sql-type="varchar(255)"/>
</property>
<property name="auth" type="java.lang.String">
<column name="auth" sql-type="varchar(255)"/>
</property>
<property name="desc" type="java.lang.String">
<column name="desc" sql-type="varchar(255)"/>
</property>
</class>
</hibernate-mapping>
News:
public class News {
private int id;
private String title;
private String auth;
private String desc;
public News() {
}
public News(String title, String auth) {
this.id = id;
this.title = title;
this.auth = auth;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuth() {
return auth;
}
public void setAuth(String auth) {
this.auth = auth;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "News{" +
"id=" + id +
", title='" + title + '\'' +
", auth='" + auth + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
测试:
public class HibernateC3p0Test {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init(){
Configuration configuration = new Configuration().configure();
//4.3.x 创建sessionFactory对象
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
//创建session对象
session = sessionFactory.openSession();
transaction = session.beginTransaction();
}
@After
public void destory(){
transaction.commit();
session.close();
sessionFactory.close();
}
@Test
public void testDoWork(){
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
System.out.println(connection);
}
});
}
}
结果: