1、什么是Hibernate?
百度百科:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JaveEE架构中取代CMP,完成数据持久化的重任。
简单来说 Hibernate是一个持久层的ORM框架。
2、什么是ORM?
Object Relation Mapping
对象关系映射。
对象-关系映射(OBJECT RELATIONAL MAPPING,简称ORM),是随着面向对象的软件开发方法发展而产生的。用来把对象模型表示的对象映射到基于SQL的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作实体对象的属性和方法。ORM技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化 。
简单的说就是把我们程序中的实体类和数据库表建立起来对应关系。
3、Hibernate开发步骤
到hibernate官网下载hibernate-release-5.x.x.Final的资源包,地址为:
如果上面链接无法下载,可以使用手机下载。
- 解压目录,目录结构如下:
documentation : Hibernate开发的文档
lib : Hibernate开发包
required : Hibernate开发的必须的依赖包
optional : Hibernate开发的可选的jar包
project : Hibernate提供的项目
- 建立Java项目
找到Hibernate根目录下的lib/required,导入里面的所有jar包到项目中:
-
在mysql数据库创建表
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-
创建实体类
public class Customer {
private Long cust_id;
private String cust_name;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_phone;
private String cust_mobile;
/* 省略get方法和set方法 */
}
-
编写*.hbm.xml对象映射文件(重点)
文件要求:
1)文件名称: 实体类名称.hbm.xml
2)文件存放的位置:和实体类存放到同一个目录下
<?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.hibernate.test.Customer" table="cst_customer">
<!-- 建立类中的属性与表中的主键对应 -->
<id name="cust_id" column="cust_id" >
<generator class="native"/>
</id>
<!-- 建立类中的普通的属性和表的字段的对应 -->
<property name="cust_name" column="cust_name" length="32" />
<property name="cust_source" column="cust_source" length="32"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
</class>
</hibernate-mapping>
-
编写hibernate.cfg.xml文件
注意:该文件建议放在项目的src目录下
<?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_day01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">abc</property>
<!-- 配置Hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- ========可选配置======== -->
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置C3P0连接池 -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
<mapping resource="com/hibernate/test/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
-
编写测试代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class HibernateDemo1 {
@Test
// 保存客户的案例
public void demo1(){
// 1.加载Hibernate的核心配置文件
Configuration configuration = new Configuration().configure();
// 手动加载映射
// configuration.addResource("com/itheima/hibernate/demo1/Customer.hbm.xml");
// 2.创建一个SessionFactory对象:类似于JDBC中连接池
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.通过SessionFactory获取到Session对象:类似于JDBC中Connection
Session session = sessionFactory.openSession();
// 4.手动开启事务:
Transaction transaction = session.beginTransaction();
// 5.编写代码
Customer customer = new Customer();
customer.setCust_name("老王");
session.save(customer);
// 6.事务提交
transaction.commit();
// 7.资源释放
session.close();
sessionFactory.close();
}
}
控制台会打印SQL语句,查看数据表会发现插入了一条语句
Hibernate:
insert
into
cst_customer
(cust_name, cust_source, cust_industry, cust_level, cust_phone, cust_mobile)
values
(?, ?, ?, ?, ?, ?)
注意:hibernate5.x.x使用hbm2ddl.auto错误,原因是<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>创建SQL语句时“......type=MyISAM ”让创建表出现错误。
修改配置方言:
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
映射配置
【class标签的配置】
标签用来建立类与表的映射关系
属性:
name :类的全路径
table :表名(类名与表名一致,table可以省略)
catalog :数据库名
【id标签的配置】
标签用来建立类中的属性与表中的主键的对应关系
属性:
name :类中的属性名
column :表中的字段名(类中的属性名和表中的字段名如果一致,column可以省略)
length :长度
type :类型
【property标签的配置】
标签用来建立类中的普通属性与表的字段的对应关系
属性:
name :类中的属性名
column :表中的字段名
length :长度
type :类型
not-null :设置非空
unique :设置唯一
hibernate.cfg.xml配置格式
Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性
每个 Hibernate 配置文件对应一个 Configuration 对象
Hibernate配置文件可以有两种格式:
- hibernate.properties(属性文件的方式,不推荐)
hibernate.properties
hibernate.connection.driver_class=com.mysql.jdbc.Driver
…
hibernate.show_sql=true
属性文件的方式不能引入映射文件(手动编写代码加载映射文件)
- hibernate.cfg.xml (XML文件的方式,推荐)
hibernate.cfg.xml
hibernate.cfg.xml的常用属性
1)JDBC 连接属性
- connection.url:数据库URL
- connection.username:数据库用户名
- connection.password:数据库用户密码
- connection.driver_class:数据库JDBC驱动
- dialect:配置数据库的方言,根据底层的数据库不同产生不同的 sql 语句,Hibernate 会针对数据库的特性在访问时进行优化
2)C3P0 数据库连接池属性
- 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: 当数据库连接池中的连接耗尽时, 同一时刻获取多少个数据库连接
- show_sql:是否将运行期生成的SQL输出到日志以供调试。取值 true | false
- format_sql:是否将 SQL 转化为格式良好的 SQL . 取值 true | false
- hbm2ddl.auto:在启动和停止时自动地创建,更新或删除数据库模式。取值 create | update | create-drop | validate
- hibernate.jdbc.fetch_size
- hibernate.jdbc.batch_size
3)jdbc.fetch_size 和 jdbc.batch_size
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 的时候比较合适。
具体详情内容可参见:http://www.yiidian.com/hibernate/