鉴于大家对JAVA十分关注,我们编辑小组在此为大家搜集整理了“Hibernate上手指南”一文,供大家参考学习
Hibernate上手
Hibernate,很久以前我就听说过这个名词,但是似乎没什么动力让我去接近它,感觉它是一个很复杂的东西,一直没搞明白它到底是用来做什么的。直到接手了一个项目在技术选型的时候我再一次的看到了Hibernate。我尝试着去使用它,发现它并不是我想像中的那么深奥,它很易用。你并不需要了解它的内部结构,它一样能为你工作的很好,如果你理解了它到底能为你做什么的话
本文着重讲述了为什么要使用Hibernate,此外也简单的介绍了如何使用Hibernate,以及Hibernate中的一些基本概念。我想借这篇文章来向还没有接触过Hibernate的开发者推荐款优秀的开源ORM产品,如果你已经实践过Hibernate,那么我想你没有必要再看下去。
一、Why Hibernate?
现在流行“测试驱动开发”,相似的我觉得“目的驱动学习”是一种比较好的接受新技术,新知识的途径。在学习一样新的技术之前,首先得明确到底有没有必要学习,已有的技术是否已经工作的很好,学习这个新的技术是为了解决什么问题。如果你明确了以上问题,那么寻找并学习新的技术将会事半功倍,并且能快速应用到实际的开发当中来提高效益。
要说Hibernate,就得先介绍一下Object/Relation Mapper(ORM),中文翻译为对象关系映射。之所以会产生这样的概念是源于目前软件开发中的一些不协调的思想。目前流行的编程模型是OOP(Object Oriented Programming),面向对象的编程,而目前流行的数据库模型是Relational Database,这两者思考的方式不一样,这必然产生了开发过程中的不协调。ORM框架(也称为持久层框架,)的出现就是为了解决这样的问题,屏蔽底层数据库的操作,以面向对象的方式提供给开发者操作数据库中数据的接口。目前流行的ORM框架有Apach OJB,Hibernate,iBatis等等,当然最完善,最好用的是Hibernate,至少我这样认为。或许你对“持久层”感到迷惑,其实说白了很简单,把数据放到数据库中叫做持久化(内存种的数据当然不是持久的),那么负责这一操作的结构层面就叫做持久层。你以前应该听说过表现层,业务层,数据层,那么持久层是在业务层和数据层之间的一层,或者说持久层是数据层的一部分。
接下来,我想通过一个实际开发中的例子来说明ORM带给我们的好处。先来讲一下我们的需求,数据库中有三张表,一张student,一张course,另外一张course_slection。其中student用来保存学生信息,course用来表示课程信息,course_selection用来表示学生的选课信息。(表的详细结构这里我就省略了,因为这并不重要)现在要求编写一个程序,用来选出指定学号学生所选的课程名字,那么可能会出现以下几种程序编写的方式:
1. 菜鸟级
代码片段1:
public List selectCourses(String studentId)
{
Connection con = null;
Statement sta = null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(
"jdbc:oracle:thin:@10.85.33.199:1521:glee",
"test", "test");
String sql = "select * from course_selection";
String sql2 = "select name from course where id=''";
sta = con.createStatement();
ResultSet rs = sta.executeQuery(sql);
List list = new LinkedList();
while (rs.next())
{
ResultSet rs2 = sta.executeQuery(sql2 +
rs.getString("course_id") + "''");
if (rs2.next())
{
list.add(rs2.getString("name"));
}
}
return list;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
这段程序你一定看的很晕吧,什么乱七八糟的都搞在一起,那么接下来看一段改进过的程序。
2. 改进后的代码
代码片段2:
class DBHelper
{
public static Connection getConnection()
{
try
{
Class.forName(Constants.DB_DRIVER);
return DriverManager.getConnection(Constants.DB_URL,
Constants.DB_USER, Constants.DB_PWD);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
public List selectCourses(String studentId)
{
Connection con = null;
Statement sta = null;
try
{
con = DBHelper.getConnection();
String sql = "select * from course_selection";
String sql2 = "select name from course where id=''";
sta = con.createStatement();
ResultSet rs = sta.executeQuery(sql);
List list = new LinkedList();
while (rs.next())
{
ResultSet rs2 = sta.executeQuery(sql2 + rs.getString("course_id") + "''");
if (rs2.next())
{
list.add(rs2.getString("name"));
}
}
return list;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
这段代码的形式是一种被广泛采用的形式,相对第一段代码来说,应该已经有所进步,分离了数据库连接操作,并把数据库连接信息交给单独的类完成(一般放在配置文件里面),往往在开发中还会引入数据库连接池(Connection Pool)来提高性能,我这里都尽量简化了。但这些并不能从根本上改善程序的结构,在业务代码中仍然混杂了很多数据库操作,结构不清晰。下面来看一段彻底分离数据库操作的代码:
3. DAO模式
代码片段3:
public List selectCourses(String studentId)
{
StudentDAO sd = new StudentDAO();
Student student = sd.findById(studentId);
Set set = student.getCourseSelections();
List courseNames = new LinkedList();
for (Iterator iter = set.iterator(); iter.hasNext();)
{
CourseSelection element = (CourseSelection) iter.next();
courseNames.add(element.getCourse()。getName());
}
return courseNames;
}
是不是感觉代码少了很多?或许你对这段代码有点迷惑,没关系,后文会详细解释。我想先解释一下DAO。其实DAO和Hibernate没有必然联系,只不过一般用Hibernate的程序都用DAO模式。DAO的全称是Data Access Object,程序要访问数据库中的数据(包括获取,更新,删除)都通过DAO来访问,实际上DAO才是真正屏蔽了所有数据库操作的东西,这样在业务代码中就可以完全隔离数据层的代码。如果我告诉你,在真正用Hibernate开发的时候,要完成上文提到的功能,需要手写的代码就是“代码片段3”这么多,甚至更少,你是不是有很大的动力去学习Hibernate?那么好吧,让我们开始Hibernate之旅。
二、持久层的组成
这一节的名字应该换成“基于Hibernate的持久层的组成”更合适一点,可是它太长了。既然Hibernate是用来开发持久层,那么我先介绍一下这个持久层中的各个元素。
1. POJO:Plain Old Java Object,你可以把它看作是简单的JavaBean。一般说来,一张数据库表对应一个POJO,也就是对象/关系的一一映射。
2. DAO:对于每一个POJO,一般都有一个DAO与之对应,承担所有关于该POJO的访问控制。实际上也就是控制了对数据库中一张表的访问控制。
3. *.hbm.xml文件:这个文件定义了POJO和数据库中的表是如何映射的,比如POJO中的字段对应数据库表中的哪个字段等等。一般每个映射都用单独的文件来描述,也就是有一个POJO就有一个*.hbm.xml文件。
4. *.cfg.xml文件:这个文件定义了Hibernate的基本信息,比如数据库驱动,用户名,密码等等连接信息,也包括了所有要用的*.hbm.xml文件,在初始化的时候,Hibernate会读取这个文件来找相应的映射文件完成对象/关系。
我们还是以上文的例子来详细描述一下这里提到的各个元素的内容。
1. Student.java:
代码片段4:
public class Student implements java.io.Serializable
{
private String id;
private String name;
private Set courseSelections = new HashSet(0);
public Student()
{
}
public String getId()
{
return this.id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return this.name;
}
public void setName(String name)
{
this.name = name;
}
public Set getCourseSelections()
{
return this.courseSelections;
}
public void setCourseSelections(Set courseSelections)
{
this.courseSelections = courseSelections;
}
}