一、什么是Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。
Hibernate的优点:
(1) 对象/关系数据库映射(ORM)
hibernate可以让开发人员以面相对象的思想来操作数据库。jdbc只能通过SQL语句将元数据传送给数据库,进行数据操作。而hibernate可以在底层对元数据和对象进行转化,使得开发者只用面向对象的方式来存取数据即可。
(2) 透明持久化(Persistent)
带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的JavaBeans/POJO,这个对象没有实现第三方框架或者接口,唯一特殊的是他们正与(仅仅一个)Session相关联。一旦这个Session被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。
(3) 事务(Transction)
应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短。它通过抽象将应用从底层具体的JDBC、JTA以及CORBA事务隔离开。某些情况下,一个Session之内可能包含多个Transaction对象。尽管是否使用该对象是可选的,但无论是使用底层的API还是使用Transaction对象,事务边界的开启与关闭是必不可少的。
(4) 移植性好
hibernate使用xml的配置以及数据库方言等等的机制,使得hibernate具有更好的移植性,对于不同的数据库,开发者只需要使用相同的数据操作即可,无需关心数据库之间的差异。而直接使用JDBC就不得不考虑数据库差异的问题。
(5) 开发效率高
hibernate提供了大量的封装(这也是它最大的缺点),很多数据操作以及关联关系等都被封装的很好,开发者不需写大量的sql语句,这就极大的提高了开发者的开发效率。
(6) 缓存机制
hibernate提供了缓存机制(一级缓存,二级缓存),对于那些改动不大且经常使用的数据,可以将它们放到缓存中,不必在每次使用时都去查询数据库,缓存机制对提升性能大有裨益。
(7) 支持透明持久化
Hibernate的API没有侵入性(即所编写的类不需要继承Hibernate的API),对于实体类来说,既可以使用普通的JDBC,也可以使用Hibernate。
Hibernate的缺点:
(1) 无法SQL优化
由于对持久层封装过于完整,导致开发人员无法对SQL进行优化,无法灵活使用JDBC的原生SQL,Hibernate封装了JDBC,所以没有JDBC直接访问数据库效率高。要使用数据库的特定优化机制的时候,不适合用Hibernate
(2) 大型项目配置复杂
Hibernate中使用ORM原则,导致配置过于复杂,一旦遇到大型项目,配置文件和内容是非常庞大复杂,不便于维护。
(3) 查询效率低
如果项目中各个表中关系复杂,表之间的关系很多,在很多地方把lazy都设置false,会导致数据查询和加载很慢,尤其是级联查询的时候。
(4) 批量处理能力弱
Hibernate在批量数据处理时有弱势,对于批量的修改,删除,不适合用Hibernate,这也是ORM框架的弱点
二、什么是ORM
对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。对象-关系映射,是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。
三、Hibernate工作原理
从图可以知道hibernate的六大核心接口,两个主要配置文件,以及他们的直接关系。
1、Configuration接口 : 负责配置并启动hibernate
2、SessionFactory接口 : 负责初始化hibernate
3、Session接口 : 负责持久化对象的CRUD操作
4、Transaction接口 : 负责事务
5、Query接口和Criteria接口 : 负责执行各种数据库查询
Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成它就被丢弃。
Hibernate工作原理:
1、解析hibernate.cfg.xml配置文件
通过Configuration config = new Configuration().configure();
Hibernate默认读取并解析hiberante.cfg.xml配置文件
2、读取并解析映射信息
hibernate.cfg.xml中的<mapping resource="com/Bean.hbm.xml"/>映射文件
3、创建SessionFactory对象
SessionFactory sessionFactory = config.buildSessionFactory();
4、打开Session
Session session = sessionFactory.openSession();
5、创建并启动事务
Transaction tx = session.beginTransaction();
6、CRUD持久化操作
7、提交事务
tx.commit();
8、关闭session
9、关闭SessionFactory
四、Hibernate开发环境搭建
(1) 引入核心jar包
hibernate5
- antlr-2.7.7.jar
- dom4j-1.6.1.jar
- geronimo-jta_1.1_spec-1.1.1.jar
- hibernate-commons-annotations-5.0.1.Final.jar
- hibernate-core-5.0.7.Final.jar
- hibernate-jpa-2.1-api-1.0.0.Final.jar
- jandex-2.0.0.Final.jar
- javassist-3.18.1-GA.jar
- jboss-logging-3.3.0.Final.jar
mysql
- mysql-connector-java-5.1.7-bin.jar
log
- log4j-1.2.16.jar
- slf4j-api-1.6.1.jar
- slf4j-log4j12-1.7.2.jar
(2) 配置文件
log --- hibernate/project/etc/log4j.properties导入到工程src下
- log4j.properties
hibernate核心配置文件 --- 放入src下 --- 参考文件:hibernate/project/etc/hibernate.properties
- hibernate.cfg.xml
hibernate实体映射文件 --- 与实体类在同一个包下,xxx表示实体类的类名
- xxx.hbm.xml
五、Hibernate简单入门实例
(1) 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>
<!-- 配置关于数据库连接的四个项 driverClass url username password -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernateTest</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 设置连接提供者 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- c3p0连接池的配置 -->
<property name="hibernate.c3p0.max_size">20</property> <!-- 最大连接池 -->
<property name="hibernate.c3p0.min_size">5</property> <!-- 最小连接数 -->
<property name="hibernate.c3p0.timeout">120</property> <!-- 超时 -->
<property name="hibernate.c3p0.idle_test_period">3000</property> <!-- 空闲连接 -->
<!-- 可以将向数据库发送的sql显示出来 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 用于设置事务提交方式 -->
<property name="hibernate.connection.autocommit">false</property>
<!-- 配置hibernate的映射文件所在位置 -->
<mapping resource="com/hibernate/domain/Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>
(2) Customer.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 package="com.hibernate.domain">
<!--
name属性它是实体类的全名
table 表的名称
catalog 数据库名称
-->
<class name="Customer" table="t_customer" catalog="hibernateTest">
<!-- id它是用于描述主键 -->
<id name="id" column="id" type="int"> <!-- java数据类型 -->
<!-- 主键生成策略 -->
<generator class="native"></generator>
</id>
<!-- 使用property来描述属性与字段的对应关系 -->
<property name="name" column="name" length="20" type="string"></property> <!-- hibernate数据类型 -->
<property name="address">
<column name="address" length="50" sql-type="varchar(50)"></column> <!-- sql数据类型 -->
</property>
<property name="sex" column="sex" length="20"></property>
</class>
</hibernate-mapping>
(3) Customer实体类
package com.hibernate.domain;
public class Customer {
private int id;
private String name;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
(4) HibernateTest1测试类
package com.hibernate.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.hibernate.domain.Customer;
public class HibernateTest1 {
//保存一个Customer
@Test
public void saveCustomerTest(){
Customer c = new Customer();
c.setName("张三");
c.setAddress("北京");
//使用hibernate的api来完成将customer信息保存到mysql中的操作
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
//相当于得到一个Connection
Session session = sessionFactory.openSession();
//开启事务
session.beginTransaction();
//操作
session.save(c);
//提交事务
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}