33.Hibernate

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如何生产sqlhibernate会根据配置的方言,生产符合当前数据库语言的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...");

 

HQLSQL区别:

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的时候,会自动引入包名;如为falsehql中对象要写上包名称

  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   表示主键自增长: 根据底层数据库的能力选择 identitysequence等其中一个。

           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>(额外的字段:用于存储mapKey

<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. NN映射

一对多与多对一映射,

可以只配置多对一, 只能通过的多的一方维护关系!

可以只配置一对多,       只能通过一的一方维护关系

双向配置: 一对多与多对一,   可以通过双向维护关系!

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>

方式2N+1张表

特点:

完全按照面向对象设计表结构!

父类一张表,每个子类一张表

总结:

设计的表,是符合数据库设计原则(三大范式)!

但是,表结构、关系变得负责,影响数据访问效率!

<joined-subclass name="Cat" table="t_cat">

<key column="id"></key>

<property name="catching"></property>

</joined-subclass>

方式3N

特点:

一个映射文件

有多少个子类对应多少个表,父类不对应表!

总结:

推荐使用!

注意:父类主键不能为自增长!

<!-- 注意:使用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    

hibernateC3p0连接池的支持

### 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>

 

转载于:https://www.cnblogs.com/fengfusheng/p/9028879.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值