本文着重讲述了为什么要使用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之旅。
心情: 非常好