参考代码下载github:https://github.com/changwensir/java-ee/tree/master/hibernate4
1、创建Hibernate.cfg.xml配置文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置连接数据库的基本信息 jdbc:mysql://localhost:3306/utils-->
<!--
<property name="connection.url">jdbc:mysql://localhost/hibernate1</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
-->
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!-- 配置 utils 的基本信息 -->
<!-- utils 所使用的数据库方言 MySQL5Dialect-->
<!--<property name="dialect">org.utils.dialect.MySQLInnoDBDialect</property>-->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- 执行操作时是否在控制台打印 SQL -->
<property name="show_sql">true</property>
<!-- 是否对 SQL 进行格式化,例如语句显示会换行 -->
<property name="format_sql">true</property>
<!-- 指定自动生成数据表的策略 -->
<property name="hbm2ddl.auto">update</property>
<!-- 配置 C3P0 数据源-->
<!--数据库连接池的最大连接数-->
<property name="hibernate.c3p0.max_size">10</property>
<!--数据库连接池的最小连接数-->
<property name="hibernate.c3p0.min_size">5</property>
<!--当数据库连接池中的连接耗尽时, 同一时刻获取多少个数据库连接-->
<property name="c3p0.acquire_increment">2</property>
<!--表示连接池检测线程多长时间检测一次池内的所有链接对象是否超时.
连接池本身不会把自己从连接池中移除,而是专门有一个线程按照一定的时间间隔来做这件事,
这个线程通过比较连接对象最后一次被使用时间和当前时间的时间差来和 timeout 做对比,进而决定是否销毁这个连接对象。-->
<property name="c3p0.idle_test_period">2000</property>
<!--数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁-->
<property name="c3p0.timeout">2000</property>
<!--缓存 Statement 对象的数量-->
<property name="c3p0.max_statements">10</property>
<!-- 设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数 ,取100最好-->
<property name="hibernate.jdbc.fetch_size">100</property>
<!-- 设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小 取20合适-->
<property name="jdbc.batch_size">30</property>
<mapping resource="hbm/News.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hbm2ddl.auto:该属性可帮助程序员实现正向工程, 即由 java 代码生成数据库脚本, 进而生成具体的表结构. 。取值 create | update | create-drop | validate
- create : 会根据 .hbm.xml 文件来生成数据表, 但是每次运行都会删除上一次的表 ,重新生成表, 哪怕二次没有任何改变
- create-drop : 会根据 .hbm.xml 文件生成表,但是SessionFactory一关闭, 表就自动删除
- update : 最常用的属性值,也会根据 .hbm.xml 文件生成表, 但若 .hbm.xml 文件和数据库中对应的数据表的表结构不同, Hiberante 将更新数据表结构,但不会删除已有的行和列
- validate : 会和数据库中的表进行比较, 若 .hbm.xml 文件中的列在数据表中不存在,则抛出异常
format_sql:是否将 SQL 转化为格式良好的 SQL . 取值 true | false
1-1.Hibernate配置文件
Hibernate 配置文件主要用于配置数据库连接和 Hibernate 运行时所需的各种属性每个 Hibernate 配置文件对应一个 Configuration 对象
Hibernate配置文件可以有两种格式:
- hibernate.properties(不推荐)
- 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 的时候比较合适。
2、创建持久化对象
public class News {
private Integer id;
private String title;
private String author;
private Date occurrenceDate;
public News(String title, String author, Date occurrenceDate) {
super();
this.title = title;
this.author = author;
this.occurrenceDate = occurrenceDate;
}
public News() {
}
//省去get,set方法
}
创建持久化 Java 类
- 提供一个无参的构造器:使Hibernate可以使用Constructor.newInstance() 来实例化持久化类
- 提供一个标识属性(identifier property): 通常映射为数据库表的主键字段. 如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate()
为类的持久化类字段声明访问方法(get/set): Hibernate对JavaBeans 风格的属性实行持久化。
- 使用非 final 类: 在运行时生成代理是 Hibernate 的一个重要的功能. 如果持久化类没有实现任何接口, Hibnernate 使用 CGLIB 生成代理. 如果使用的是 final 类, 则无法生成 CGLIB 代理.
- 重写 eqauls 和 hashCode 方法: 如果需要把持久化类的实例放到 Set 中(当需要进行关联映射时), 则应该重写这两个方法
Hibernate 不要求持久化类继承任何父类或实现接口,这可以保证代码不被污染。这就是Hibernate被称为低侵入式设计的原因
Hibernate 采用 XML 格式的文件来指定对象和关系数据之间的映射. 在运行时 Hibernate 将根据这个映射文件来生成各种 SQL 语句
映射文件的扩展名为 .hbm.xml
3、创建对象--映射文件
创建完后,需要所这个文件配置到hibernate.cfg.xml里
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.changwen.hibernate4.session.sessionPojo">
<class name="News" table="NEWS" dynamic-update="true">
<!-- name的内容是这个类的属性名-->
<id name="id" type="java.lang.Integer">
<!-- name的内容是数据库的字段名(列名)-->
<column name="ID" />
<!-- 指定主键生成的方式,native: 使用数据库本地方法,如Mysql使用自增,Oracle使用序列-->
<generator class="native" />
</id>
<property name="title" type="string" column="TITLE"
unique="true" update="false" index="news_index" length="20">
</property>
<property name="author" type="java.lang.String" index="news_index">
<column name="AUTHOR" />
</property>
<property name="occurrenceDate" type="java.util.Date">
<column name="occurrenceDate" />
</property>
</class>
</hibernate-mapping>
4、测试访问数据库
后面的测试都以这个为基础,请注意
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init(){
// 创建 Configuration 对象: 对应 utils 的基本配置信息和 对象关系映射信息
Configuration configuration = new Configuration().configure();
// 创建一个 ServiceRegistry 对象: utils 4.x 新添加的对象
//utils 的任何配置和服务都需要在该对象中注册后才能有效.
ServiceRegistry serviceRegistry =
new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
//创建一个 Session 对象
session = sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction();
}
@After
public void destroy(){
//提交事务 :真正与数据库交互的语句
transaction.commit();
//关闭 Session
session.close();
//关闭 SessionFactory 对象
sessionFactory.close();
}
<pre name="code" class="java"> @Test
public void test() {
}
如果创建表成功就完成本实例
4-1.Configuration 类
Configuration 类负责管理 Hibernate 的配置信息。包括如下内容:
- Hibernate 运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等(对应 hibernate.cfg.xml 文件)。
- 持久化类与数据表的映射关系(*.hbm.xml 文件)
创建 Configuration 的两种方式
- 属性文件(hibernate.properties):
·Configuration cfg = new Configuration();
- Xml文件(hibernate.cfg.xml)
·Configuration cfg = new Configuration().configure();
- Configuration 的 configure 方法还支持带参数的访问:
·File file = new File(“simpleit.xml”);
·Configuration cfg = new Configuration().configure(file);
4-2.SessionFactory 接口
- 针对单个数据库映射关系经过编译后的内存镜像,是线程安全的。
- SessionFactory 对象一旦构造完毕,即被赋予特定的配置信息
- SessionFactory是生成Session的工厂
- 构造 SessionFactory 很消耗资源,一般情况下一个应用中只初始化一个 SessionFactory 对象。
- Hibernate4 新增了一个 ServiceRegistry 接口,所有基于 Hibernate 的配置或者服务都必须统一向这个 ServiceRegistry 注册后才能生效
- Hibernate4 中创建 SessionFactory 的步骤见测试类前三条代码
4-3.Session 接口
Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处。相当于 JDBC 中的 Connection。
持久化类与 Session 关联起来后就具有了持久化的能力。
Session 类的方法:
-取得持久化对象的方法: get() load()
-持久化对象都得保存,更新和删除:save(),update(),saveOrUpdate(),delete()
-开启事务: beginTransaction().
-管理 Session 的方法:isOpen(),flush(), clear(), evict(), close()等
4-4.Transaction(事务)
代表一次原子操作,它具有数据库事务的概念。所有持久层都应该在事务管理下进行,即使是只读操作。
Transaction tx = session.beginTransaction();
常用方法:
commit():提交相关联的session实例
rollback():撤销事务操作
wasCommitted():检查事务是否提交