假设我们需要开发一个学生信息管理系统,那么难免需要编写和数据库交互的代码,也就是我们经常所说的数据
持久层,在此之前我们已经编写过大量的持久层代码,也就是JavaBean和Dao。
下面就设计一个学生实体类:
package com.demo.domain;
import java.util.Date;
/**
* 学生实体类
* @author Administrator
* @date 2016年12月3日
*/
public class Student {
private int sid;
private String sname;
private String gender;
private Date birthday;
private String address;
public Student(){
}
public Student(int sid, String sname, String gender, Date birthday, String address) {
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.address = address;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", gender=" + gender + ", birthday=" + birthday
+ ", address=" + address + "]";
}
}
需要在关系数据库中建立数据库,创建对应的数据表,也就是生成一张这样的数据表student:
然后我们根据这个实体类生成很多的学生对象,保存在关系型数据库中的一种表里,那么这个过程需要我们写大
量的SQL语句。
写SQL语句有什么不好吗?
不同的数据库使用的SQL语法不同。比如:PL/SQL与T/SQL;
同样的功能在不同的数据库中有不同的实现方式。比如分页SQL;
程序过分依赖SQL对程序的移植及扩展,维护等带来很大的麻烦;
那么我们有什么思路去放弃写大量SQL语句的过程,使用面向对象的思维去开发数据持久化层呢?那么
Hibernate框架就是一个ORM框架。
如果学习过JavaWeb的话,那么对于经典的三层架构就不会陌生了,三层架构的三层分别指的是界面层、业务逻
辑层、数据持久层。在JavaWeb中,界面层和业务逻辑层可以使用Struts框架来封装一些常用的操作。而在我们的数
据持久层中,对数据库的增删改查,我们经常要手动的控制事务,各种SQL语句查询,各种参数传递,无论是对哪个
表操作使用的均是同一种思路进行操作的。既然是同一种思路,那就是重复的东西了。而且我们还要和关系型数据库
打交道,而不单单的是对象。而Hibernate框架对此作了完美的封装,那么我们可以使用Hibernate使我们采用面向
对象的思维操作关系型数据库,这样就和我们的思维形式一致了。
在学习Hibernate框架之前,首先需要了解ORM框架。
ORM的全称是ORM(Object/Relationship Mapping):对象/关系映射。利用面向对象思想编写的数据库应用程
序最终都是把对象信息保存在关系型数据库中,于是要编写很多和底层数据库相关的SQL语句。这个思想与面向对象
是截然不同的。
ORM是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对
象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换
到另外一种形式。
面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数
据的主流数据存储系统。字母O起源于“对象”(Object),而R则来自于“关系”(Relational)。几乎所有的程序里
面,都存在对象和关系数据库。在业务逻辑层和呈现层中,我们是面向对象的。当对象信息发生变化的时候,我们需
要把对象的信息保存在关系数据库中。
当你开发一个应用程序的时候(不使用ORM),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取
对象信息,等等。而这些代码写起来总是重复的。
把数据保存到数据库或者某些存储设备中。在三层架构中,持久化是和数据库打交道的层次。在Jsp的Web开发
中,经常有许多数据库连接、删除、查询等操作,在数据库相关工作中通过JDBC过于繁琐,就催生出了ORM框架,
ORM作用是在关系数据库和对象之间做一个自动映射,这样在操作数据库时不需要使用复杂的sql语句,只要操作对
象即可,ORM工具会自动将对象转换为SQL语句操作。这样就只需要关注业务逻辑中的对象结构,而不用关心底层复
杂的SQL和JDBC代码。而Hibernate框架是ORM框架的一种,是关系/对象映射的解决方案。
ORM框架:
其他主流的ORM框架技术:
MyBatis:前身就是著名的iBatis
Toplink:后被Oracle收购,并重新包装为Oracle AS TopLink
EJB:本身是JavaEE的规范(重量级框架)
Hibernate框架是一个基于Java的对象/关系数据库映射工具,它将对象模型表示的数据映射到SQL表示的关系模
型上去。Hibernate管理Java到数据库的映射,提供给了数据查询和存取的方法,减少了程序员对数据持久化层相关
的编程任务。
Hibernate框架是一个对象/关系映射框架,专门用于将对象模型表示的对象映射到关系型数据库结构。
Hibernate框架是Java领域的一款开源的ORM框架技术。Hibernate框架对JDBC进行了非常轻量级的对象封装。
对象/关系映射一直都是数据库技术中的难点,尽管人们提出了许多方案解决这个问题,但都不能完全做到即便利
又高效。EJB的推出让人们看到了希望,但实践证明实体Bean的效率并不高,并且还十分难于为初学者理解。由
Gavin King创建的Hibernate框架,从某种程序上正在朝着正确的方向迈走,并且得到越来越多IT从业人员的认可。
就像当年的Struts框架一样,Hibernate也已经在许多项目中得到广泛应用。Hibernate由于投注了更多的精力在提升
效率上,使用起来又十分方便,新版的EJB规范正在向Hibernate方向靠拢。正是由于得到广泛的认可,Hibernate已
经成为程序员必须掌握的技术之一。
Hibernate在应用程序中充当的角色:
Hibernate框架角色:
Hibernate的核心类和接口一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和
Configuration。这6个核心类和接口在任何开发中都会用到。通过这些接口,不仅可以对持久化对象进行存取,还能
够进行事务控制。下面对这6个核心接口和类分别加以介绍。
Session
Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语
句)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的Session不同于JSP应用中的HttpSession。这
里当使用Session这个术语时,其实指的是Hibernate中的Session,而以后会将HttpSession对象称为用户Session。
对于Session我们是那么的熟悉,在JavaWeb开发中Session可以用来保存用户会话过程中状态信息。而
Hibernate中的Session是对象与数据库会话持久化管理器。
会话是单线程、声明短暂的对象,代表应用和持久化层之间的一次对话,封装了JDBC连接,事务的工程。保存必
需持久化对象缓存,用于遍历对象图,或者表示查找对象。
SessionFactory
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工
厂模式。需要注意的SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一SessionFactory就
够,当需要操作多个数据库时,可以为每个数据库指定一SessionFactory。
会话工厂是对属于单一数据库的映射文件的线程安全的、不可变的缓存快照。它是会话的工厂类,可能持有一个
可选的(二级)数据库缓存,可以在进程级别或集群级别保存可以在事务中重用的数据。
Transaction
Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate 的设计者自己写的底层
事务处理代码。 Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的
UserTransaction、甚至可以是CORBA 事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得
自己的项目可以在不同的环境和容器之间方便地移植。
单线程,应用程序用它表示一批不可分割操作。一个Session在某些情况下可能跨越多个事务。
Query
Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语
句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
Criteria
Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻
量级的,它不能在Session之外使用。
Configuration
Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,
Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然
Configuration 类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对
象。
优点:
由于使用了Hibernate,代码中不涉及具体的JDBC语句,所以就方便了代码的可移植性;
我们用Java开发程序,则使用面向对象的思想,使用Hibernate可以使我们采用对象化的思维操作关系型数据
库,Hibernate两种不同的模型之间建立关联,Hibernate给我们提供了利用面向对象的思想来操作关系型数据的接
口;使开发更加对象化(阻抗不匹配);
Hibernate框架是一个轻量级框架,没有侵入性,没有侵入性,支持透明持久化;
直接使用JDBC操作数据库的步骤很繁琐,而使用Hibernate框架很高效,可以提高生产力;
缺点:
封装的太彻底导致不灵活,是用数据特定的东西比较不容易;
对大量数据库的更新有问题,当程序大量查询统计,或批量更新无法使用数据库特性机制,例如存储过程等;
使用数据库特性的语句,将很难调优;