1. Hibernate框架
1.1 ORM 规则
ORM, Object Relation Mapping 对象关系映射!
目标:
通过orm(对象关系映射), 可以做到:
a. 不写sql,包对象直接保存到数据库中
b. 不写sql, 从数据库中读取,直接获取的是封装好的对象!
ORM是一种思想,或者说是一种规则的定义, 基于orm的应用:
1. hibernate 框架
2. mybatis 框架
3. 自定义一套程序!
1.2 Hibernate概念
基于ORM的持久层框架,对jdbc操作进行了封装!
Hibernate与具体数据库无关的技术,即可以框数据库平台!
1.3 Hibernate开发环境搭建
实现步骤:
1. 建库、建表 |
-- 删除数据库 DROP DATABASE hib_demo; -- 创建数据库 CREATE DATABASE hib_demo DEFAULT CHARACTER SET utf8; -- 建表 CREATE TABLE users( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), age INT ) |
2. 引入hibernate核心jar文件 |
源码中:hibernate3.jar + required 目录中所有 + jpa + 数据库驱动包 |
3. 主配置文件: hibernate.cfg.xml |
<!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.url">jdbc:mysql:///hib_demo</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 通过数据库方言,告诉hibernate如何生产sql。 hibernate会根据配置的方言,生产符合当前数据库语言的SQL语句 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- hibernate其他常用配置 --> <property name="hibernate.show_sql">true</property> <!-- 查看hibernate生成的sql语句 --> <property name="hibernate.format_sql">true</property><!-- 格式化sql语句 --> <property name="hibernate.hbm2ddl.auto">update</property><!-- 自动建表 --> <!-- 二、映射配置加载映射 --> <mapping resource="cn/itcast/b_api/Users.hbm.xml"/> </session-factory> </hibernate-configuration> |
4. javabean/ 映射文件(Users.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"> <!-- 通过XML映射,把对象映射到数据库的表中!--> <hibernate-mapping package="cn.itcast.a_config"> <class name="Users" table="users"> <id name="userId" column="id"> <generator class="native"></generator> </id> <property name="userName" column="name"></property> <property name="age" column="age"></property> </class> </hibernate-mapping> |
5. 测试类 |
public class App { private static SessionFactory sf; static { // 1. 创建配置管理器对象 Configuration config = new Configuration(); // 2. 加载主配置文件, 默认加载src/hibernate.cfg.xml config.configure(); // 3. 根据加载的主配置文件,创建SessionFactory对象 sf = config.buildSessionFactory(); } // 保存 public void testSave() throws Exception { Users users = new Users(); users.setUserName("Jack"); users.setAge(30); // 4. 创建Session对象 Session session = sf.openSession(); // 5. 开启事务 Transaction tx = session.beginTransaction(); // --- 保存 session.save(users); // 6. 提交事务/关闭session tx.commit(); session.close(); } // 获取对象 public void testGet() throws Exception { // 4. 创建Session对象 Session session = sf.openSession(); // 5. 开启事务 Transaction tx = session.beginTransaction(); // --- 获取 (根据主键查询) Users users = (Users) session.get(Users.class, 1); // 6. 提交事务/关闭session tx.commit(); session.close(); } } |
2. Hibernate框架Api
|-- Session 一个与数据库连接的会话信息
Sesison里面维护了一个连接对象,且对常用操作进行封装!
更新:
session.save(obj); 保存一个对象
session.update(obj) 更新一个对象, 注意修改对象的主键一定要在数据库存在!
session.saveOrUpdate(obj) 保存或更新
如果有设置主键且主键存在执行更新!
没有设置主键执行保存!
session.delete(obj) 删除一个对象; 注意修改对象的主键一定要在数据库存在!
主键查询:
session.get(clazz,id); 根据主键查询
session.load(clazz,id); 根据主键查询
HQL查询:
Hibernate Query language
Hibernate提供的面向对象的查询语言!
查询的是对象、对象的属性!
Query q = session.createQuery("from Users Where..."); |
HQL与SQL区别:
Hql 查询的是对象、对象的属性, 区分大小写!
Hql查询的对象一定要有映射!
SQL 查询的是表、字段,不区分大小写!
3. hibernate.cfg.xml 配置详解
在主配置文件配置的时候,hibernate 前缀可以省略!
查看配置提示:
hibernate-distribution-3.6.0.Final\project\etc\hibernate.properties
里面有常用配置,如:
#hibernate.dialect => org.hibernate.dialect.MySQLDialect
#hibernate.connection.driver_class => com.mysql.jdbc.Driver
#hibernate.connection.url => jdbc:mysql:///test
#hibernate.connection.username => root
#hibernate.connection.password =>root
自动建表:
#hibernate.hbm2ddl.auto =>create
create-drop 每次在创建sessionFactory的时候创建表;执行sf.close()删除表。
create 每次都先删除表,再创建新的表
update 如果表不存在则创建,存在就不创建!
validate 检查映射配置与数据库结构是否一致,不一致就报错! (严格)
也可以通过代码的方式,自动建表:
//代码方式自动建表 public static void main(String[] args) { // 创建配置管理器对象,加载主配置文件(会加载映射) Configuration cfg = new Configuration().configure(); // 自动建表工具类 SchemaExport export = new SchemaExport(cfg); // 创建表: 第一个参数: 是否打印建表语句到控制台 // 第二个参数: 是否执行脚本,生成表 export.create(true, true); } |
4. 映射配置
映射文件,
命名: *.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"> <!-- package 表示包名; 可选,如果没有写,后面的类必须指定类的全名! auto-import="true" 默认为true,即在写hql的时候,会自动引入包名;如为false,hql中对象要写上包名称 Query q = session.createQuery("from Users"); --> <hibernate-mapping package="cn.itcast.b_api" auto-import="true"> <!-- class 表示映射的一个javabean对象 (可以有多个class节点,但一般一个映射文件对应一个class) name 表示映射的类的名称; table (可选)类的名称,对应的表名, 如果不写默认与类名称一样 --> <class name="Users" table="t_users"> <!-- id 表示映射的是主键(表必须要有主键!) generator 表示的是主键生成策略 (Api :Various additional generators) class identity 主键自增长, mysql/sqlservlet等数据库使用的自增长的方式 sequence 以序列的方式实现自增长; native 表示主键自增长: 根据底层数据库的能力选择 identity、sequence等其中一个。 assigned 手动指定主键的值 uuid uuid的值作为主键,确保一定唯一 --> <id name="userId" column="id"> <generator class="native"></generator>(自增长) </id> <!--property 表示普通字段的映射 name:JavaBean属性的名称 column:表中字段名。可选,(默认与属性名称一致) length:表示字符长度,只对字符类型有效,(默认255) type:数据库中字段的类型(默认会匹配属性的类型) hibernate中指定的类型: 小写开头 java中类型: 写类的全名 unique:设置为true,表示给当前列添加唯一约束(默认false) --> <property name="userName" type="java.lang.String" column="username" length="50" unique="true"></property> <!-- 注意:如果列名称对应的是数据库的关键字,需要处理 --> <property name="desc" column="`desc`"></property> </class> </hibernate-mapping> |
5. 联合主键映射
数据库,联合主键:(两个字段作为主键) |
-- 联合主键 (hbm: <composite-id></composite-id> ) CREATE TABLE test( id1 INT, id2 INT, PRIMARY KEY(id1,id2) ); |
javabean:
// 联合主键对象, 必须要实现可课序列化标记! public class CompositeKeys implements Serializable{ private String name; private String address; } |
// 员工javabean public class Employee { // 联合主键对象 private CompositeKeys keys; private String dept; private Date birth; } |
Employee的映射: |
<hibernate-mapping package="cn.itcast.c_composite"> <class name="Employee" table="t_employee"> <composite-id name="keys"> <key-property name="name"></key-property> <key-property name="address"></key-property> </composite-id> <property name="dept" length="50"></property> <property name="birth" type="date"></property> </class> </hibernate-mapping> |
6. Session缓存
Session缓存,也叫做一级缓存! 当Session关闭后,一级缓存内容失效!
当执行session的相关方法,如: save()/update()/get()/load()等方法的时候,对象会自动放入一级缓存中。
特点:
1)缓存有效范围,只在当前session范围内有效! 缓存时间很短、作用范围小!
2)一级缓存,可以在短时间内多次操作数据库的时候,才会明显提升效率!
一级缓存的结构:Ma<主键,对象>
3)在提交事务时候,
Hibernate会同步缓存数据到数据库中,会对比缓存数据与数据库数据是否一致,如果不一致,才提交更改到数据库(生成update)!
4) hibernate提供的一级缓存有hibernate自身维护,如果想操作一级缓存内容,必须通过hibernate提供的方法;
session.flush(); 手动让让一级缓存内容与数据库同步
session.evict(emp1); 清空一级缓存中对象: 清除指定的对象
session.clear(); 清空一级缓存中对象: 清除所有的对象
两种创建创建方式 SessionFactory sf= new Configuration().configure().buildSessionFactory(); |
1.创建 |
sf.openSession(); |
2.线程创建(非C3P0线程池) |
<property name="hibernate.current_session_context_class">thread</property> |
sf.getCurrentSession(); |
7. lazy 属性
Hibernate为了提升程序运行效率,提供了懒加载!
懒加载: 用到数据的时候,才向数据库发送查询的sql!
lazy 属性表示懒加载!
true :默认支持懒加载,只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其集合元素的数据。
false 关闭懒加载,即在加载对象的同时,就发出查询语句加载其集合的数据。
extra 聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate并不会去加载集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载对象的数据。
(1) 主键查询:
get/load
get:
及时加载, 只要get就立刻查询数据库
如果查询的主键不存在,返回null
Load:
懒加载, 只有在用到数据的时候,才向数据库发送sql语句!
如果查询的主键不存在,只要使用就报错!
(2) 懒加载作用位置
类级别,默认支持懒加载,但只有在使用load使用才会应用这个特性!
字段级别, 普通字段无效,大数据类型会有影响(long/longtext)
集合属性, 默认支持懒加载
(3) 懒加载异常
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
解决思路:
1)在关闭后,不能使用懒加载的数据,那么就要求关闭前把懒加载使用的数据先查询出来!
Hibernate.initialize(对象);
(使用懒加载数据)注意:在映射中,必须使用到对象的属性
2)使用query查询中的迫切连接查询。
8. 集合映射
为主表添加外部副表:(类似一对多)
<hibernate-mapping package="cn.itcast.c_collection"> <class name="Users" table="t_users"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="name" length="50"></property> <!-- 集合属性的映射 映射到的表: t_address 指定外键字段: user_id 外键字段之外的其他字段的映射, address --> <set name="addressSet" table="t_address"> <key column="user_id"></key> <element column="address" type="string"></element> </set> <!-- list集合映射 --> <list name="addressList" table="t_addressList"> <key column="user_id"></key> <list-index column="idx_"></list-index>(额外的字段:用于存储放置进去的顺序) <element column="address" type="string"></element> </list> <!-- map集合的映射 --> <map name="addressMap" table="t_addressMap"> <key column="user_id"></key> <map-key column="shortName" type="string"></map-key>(额外的字段:用于存储map的Key) <element column="address" type="string"></element> </map> </class> </hibernate-mapping> |
// set集合 private Set<String> addressSet; // list集合 private List<String> addressList; // map集合 private Map<String,String> addressMap; |
// 地址对象 Set<String> addressSet = new HashSet<String>(); addressSet.add("骏景花园"); addressSet.add("天朗明居"); // 用户 Users user = new Users(); user.setName("老许"); // 关系 user.setAddressSet(addressSet); |
user.getAddressSet(); // 懒加载(当get的时候才会查询Address表) |
9. N对N映射
一对多与多对一映射,
可以只配置多对一, 只能通过的多的一方维护关系!
可以只配置一对多, 只能通过一的一方维护关系
双向配置: 一对多与多对一, 可以通过双向维护关系!
1)多对一(建议)
实现:多个对象中维护同一个对象
多对一映射: <!-- 多对一的配置: 1.name=>映射的对象 2.column=>对象对应的外键字段 3.class=>对象的类型(全名,包相同可以只写类名) 注意: 对象一定是有映射文件进行映射!(cn.itcast.d_many2one.Users 对应也要有映射文件) --> <many-to-one name="user" column="user_id" class="Users"></many-to-one> |
public class Address { private int id; private String name; private String shortName; private String code; // 一个用户对应多个地址 private Users user; } |
session.save(users); session.save(address_gz); session.save(address_sz); |
2)一对多
实现:一中维护一个多的集合
<!-- 一对多映射: 1. name=>映射的集合属性: address 2. table=>集合属性,映射到的表: t_address 3. column=>表的外键: user_id 4. class=>集合属性的类型:Address --> <set name="address" table="t_address"> <key column="user_id"></key> <one-to-many class="Address"/> </set> |
public class Users { private int id; private String name; private int age; // 用户与地址,是一对多的关系 【注意一定要用接口接收!】 private Set<Address> address = new HashSet<Address>(); } |
3)多对多
实现:多个对象中维护一个多的集合(数据库中会添加一个新的关系表)
//projects配置 <set name="projects" table="t_relation"> <key column="person_id"></key> <many-to-many column="project_id" class="Project"></many-to-many> </set> //person配置 //inverse="true"表示当前对象不能维护中间表。 <set name="person" table="t_relation" inverse="true" lazy="extra"> <key column="project_id"></key> <many-to-many column="person_id" class="Person"></many-to-many> </set> |
//projects类 private Set<Person> person = new HashSet<Person>(); //person类 private Set<Project> projects = new HashSet<Project>(); |
//可以互相维护,但是不能重复添加相同的 project_crm.getPerson().add(p_wl); project_oa.getPerson().add(p_lc); p_wl.getProjects().add(project_oa); // 保存 session.save(project_crm); session.save(project_oa); session.save(p_wl); session.save(p_lc); |
4)一对一
实现:一个对象中维护另一个对象
无外键方(主表)idCard <one-to-one name="user" class="User"></one-to-one> 有外键方:user(unique="true"唯一约束) <many-to-one name="idCard" column="card_id" class="IdCard" unique="true"></many-to-one> |
private User user; |
user.setIdCard(idCard); // 保存 session.save(idCard); session.save(user); |
特殊的一对映射:外键字段就是自身的主键字段
主表:idCard <one-to-one name="user" class="User"></one-to-one> 副表: user <id name="id"> <!-- 指定了主键生成策略为“外键策略”, 把别的表的主键作为当前表的主键! --> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <--(constrained="true":在主键上,添加外键约束!)--> <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one> |
使用方法和普通一对一一致 |
10. 组件映射
对象之间的关系:
组件映射:组合关系, 一个类中包含对另外一个类的引用,这2个类就是组合关系!
继承映射:继承关系,一个类继承另外一个类!
实现:组件类和包含的组件类同时映射到一个表
<component name="wheel" class="Wheel"> <property name="count"></property> <property name="size"></property> </component> |
注:一对一是两张表,组合映射是一张表,wheel对象的属性作为表中的字段存储,只需要session.save(car); |
11. 继承映射
1)简单继承映射
特点:
父类、子类写到一个映射文件中!
有多少个子类,要写多少个映射文件.
总结:
缺点就是映射文件过多!
<hibernate-mapping package="cn.itcast.f_extends1"> <class name="Dog" table="t_dog"> <!-- 继承父类的属性,直接写 --> <id name="id"> <generator class="native"></generator> </id> <!-- 子类属性 --> <property name="play" length="20"></property> </class> </hibernate-mapping> |
2)复杂继承映射
方式1:一张表
特点:
所有的子类都写到一个映射文件中!
用一张表存储所有的子类信息!
总结:
生成的表,不符合数据库设计原则!
因为所有子类都用一张表存储,存在很大的冗余字段!
<!-- 指定鉴别器字段,用于区分不同的子类信息 --> <discriminator column="type_"></discriminator> <!-- discriminator-value 指定鉴别器字段的值,如果没有指定,默认是类的全名! --> <subclass name="Cat" discriminator-value="cat_"> <property name="catching"></property> </subclass> |
方式2:N+1张表
特点:
完全按照面向对象设计表结构!
父类一张表,每个子类一张表
总结:
设计的表,是符合数据库设计原则(三大范式)!
但是,表结构、关系变得负责,影响数据访问效率!
<joined-subclass name="Cat" table="t_cat"> <key column="id"></key> <property name="catching"></property> </joined-subclass> |
方式3:N张表
特点:
一个映射文件
有多少个子类对应多少个表,父类不对应表!
总结:
推荐使用!
注意:父类主键不能为自增长!
<!-- 注意:使用union-subclass要求主键不能自增长! --> <class name="Animal" abstract="true">(抽象,Animal不生成表) <union-subclass name="Cat" table="t_cat"> <property name="catching"></property> </union-subclass> |
12. cascade 级联操作
cascade级联是指操作主对象时,对关联的对象也做相应的操作。
,在一对多、多对一、一对一种都可以设置
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上
none 不级联(默认值)
<set name="employees" cascade="save-update,delete"> |
13. query查询
<!-- 定义hql查询 --> <query name="my_hql_select"> <!-- from Dept where id < 4 --> <!-- CDATA区,可以对批量转译 --> <![CDATA[ from Dept where id < 4 ]]> </query> |
a. 查询所有列 Query q = session.createQuery("from Dept"); Query q = session.createQuery("from Dept d"); // b. 查询指定的列 // 注意: 一旦指定了查询的列,返回的就不是对象了! Query q = session.createQuery("select d.id,d.deptName from Dept d"); List<Object[]> list = q.list(); // 迭代 for (Object[] obj : list) { System.out.println(Arrays.toString(obj)); } // c. 查询指定的列,自动封装为对象 q = session.createQuery("select new Dept(d.id,d.deptName) from Dept d"); System.out.println(q.list()); // 占位符 Query q = session.createQuery("from Dept where deptName=?"); q.setParameter(0, name); // jdbc参数是从1开始,这里从0开始! // 命名参数查询 Query q = session.createQuery("from Dept where deptName = :name_"); q.setParameter("name_", name); // 从配置文件中,读取hql,便于后期维护 Query q = session.getNamedQuery("my_hql_select"); |
连接查询:尽量不使用懒加载,使用连接查询可以只查询需要的数据,并且不会懒加载 |
// 迫切内连接, 会自动封装数据 Query q = session.createQuery("from Employee e inner join fetch e.dept"); // 迫切左外连接, q = session.createQuery("from Employee e left join fetch e.dept"); |
14. 二级缓存
Hibernate提供的缓存分类:
一级缓存
基于sessoin的缓存!
特点:
1. 在短时间内多次操作数据库情况下,缓存效果比较明显!
2. session关闭后,就不能使用缓存内容!
二级缓存:
基于应用程序的缓存、基于sessionFactory级别的缓存!
缓存数据可以被多个session共享! 但需要指定哪些对象要放入二级缓存中!
放入二级缓存中对象的特点:
1. 经常使用
2. 不会被经常修改!
Hibernate提供的二级缓存是以缓存框架形式提供,hibernate提供了二级缓存框架默认的实现; 也支持其他二级缓存框架,如果要更换缓存,只要更换配置中具体的二级缓存框架使用的核心类即可!可插配的缓存框架!
配置参考:
Hibernate提供的二级缓存配置。参考:hibenrate.properties配置文件
hibernate-distribution-3.6.0.Final\project\etc\hibernate.properties
## disable the second-level cache 【二级缓存默认为关闭】
#hibernate.cache.use_second_level_cache false
## enable the query cache 【是否开启查询缓存】
#hibernate.cache.use_query_cache true
## choose a cache implementation【二级缓存实现框架的种类】
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider (默认)
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
步骤:
1) 配置=>hibernate.cfg.xml |
1) 开启二级缓存 <property name="hibernate.cache.use_second_level_cache">true</property> 2) 指定使用哪一种二级缓存 <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property> 3) 加入二级缓存的类 <class-cache usage="read-write" class="cn.itcast.b_second_cache.Dept"/> |
缓存策略: |
usage="read-write" 二级缓存的数据可以读、写 usage="read-only" 二级缓存的数据只读 usage="nonstrict-read-write" 非严格读取 usage="transactional" 基于事务的策略 |
集合缓存(集合缓存,集合元素(Employee)也要放入二级缓存) |
4)<class-cache usage="read-write" class="cn.itcast.b_second_cache.Employee"/> 5)<collection-cache usage="read-only" collection="cn.itcast.b_second_cache.Dept.employees"/> |
查询缓存:List()查询 à 不会从session缓存获取数据 à 默认不会从二级缓存获取数据,但可以指定从二级缓存获取! |
2.5)开启查询缓存 <property name="hibernate.cache.use_query_cache">true</property> |
// 放入二级缓存或者从二级缓存中获取 Query q = session1.createQuery("from Dept").setCacheable(true); |
注意:更新数据,一级缓存session不会更新、二级缓存会检测到,并重新查询 |
15. SQLQuery 查询
Hibernate除了支持面向对象的查询外,还支持原生态的sql语句查询,在数据库段写好的sql也可以直接在hibernate中执行!(也可以写到配置文件中,标签类型sql-query)
优缺点:
1 . 对于一些比较负责的查询, hql实现不了, 这时候,本地sql查询就可以作为补充!
2. 使用本地sql查询不能跨数据库平台! 一旦更换了数据库,sql语句有可能会更改!
SQLQuery q = session.createSQLQuery("select * from t_dept"); List<Object[]> list = q.list(); // 把每一行数据封装为Object[] ,再添加到list集合 q.addEntity(Dept.class);// 把查询到的结果,自动封装为对象 (对象必须有映射文件) |
16. Hibernate 对连接池支持
连接池:
开源的连接池组件C3p0!
连接池:
管理连接,提高连接的使用效率!
Hibernate对连接的支持:
查看hibernate.properties
hibernate自带的连接池,只有一个连接!
### Hibernate Connection Pool ###
hibernate.connection.pool_size 1
hibernate对C3p0连接池的支持
### C3P0 Connection Pool###
#hibernate.c3p0.max_size 2
#hibernate.c3p0.min_size 2
#hibernate.c3p0.timeout 5000
#hibernate.c3p0.max_statements 100
#hibernate.c3p0.idle_test_period 3000
#hibernate.c3p0.acquire_increment 2
#hibernate.c3p0.validate false
C3p0连接池驱动类
#hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider
hibernate项目中使用c3p0连接池:
0. 引入c3p0驱动包
1. 配置c3p0驱动类
2. 连接池参数配置
<!-- hibernate对连接池的支持--> <!-- C3p0连接池支持类 --> <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 最大连接数 --> <property name="hibernate.c3p0.max_size">6</property> <!-- 最小连接数 --> <property name="hibernate.c3p0.min_size">4</property> <!-- 当连接不够用时候每次的增量 --> <property name="hibernate.c3p0.acquire_increment">2</property> <!-- 最多执行的命令的个数 --> <property name="hibernate.c3p0.max_statements">100</property> <!-- 连接空闲测试时间 --> <property name="hibernate.c3p0.idle_test_period">3000</property> |