1.4 Java程序通过Hibernate API访问数据库
悟空掌握了JDBC API的用法后,洋洋得意了一阵,觉得自己更加神通广大了。但是过了一阵,它发现用JDBC API来访问数据库时,以1.3 节的例程1-2 的BusinessService类的saveMonkey()方法为例,由于在程序代码中嵌入了SQL语句,会导致以下弊端:
● 编程人员必须既懂Java语言,又懂SQL语言,才能编写数据库访问代码。
● 程序代码中嵌入大量字符串形式的SQL语句,降低了程序代码的可读性。
● 程序代码与关系数据库结构绑定在一起,削弱了程序代码的独立性和可维护性。例如,当数据库中MONKEYS表的结构发生了改变,比如修改了一个字段的名字,那么程序代码中所有涉及MONKEYS表的SQL语句也要做相应修改。
● 当编程人员试图向数据库中存入一个Monkey对象时,他需要了解与Monkey对象对应的表为MONKEYS表,与Monkey对象的name属性对应的字段为NAME字段,依次类推。因此编程人员必须即熟悉对象模型,又熟悉关系数据模型,还要了解两者的对应关系。所以编程人员不能完全按照面向对象的思维来编写程序代码。
为了解决以上弊端,悟空引进了一种目前很流行的工具软件,名为Hibernate。Hibernate本身也完全用Java语言编写出来,并且它对JDBC API进行了封装,能提供更加面向对象的数据库访问API,参见图1-10。
图1-10 Java程序通过Hibernate API来访问数据库
Hibernate API中最核心的一个接口就是Session接口,通过Session接口来向数据库中存入一个Monkey对象非常简单,只要调用它的save()方法就行了:
//嗨,Session总管,拜托帮我把一个Monkey对象保存到数据库中。 session.save(monkey);
以上程序代码多么简洁呀,程序代码中不涉及任何SQL语句,因此是纯粹的面向对象的程序代码。程序代码只需轻轻松松地向Session接口发送一条消息:“嗨,Session总管,拜托帮我把一个Monkey对象保存到数据库中”,至于到底如何把一个Monkey对象保存到数据库中,就完全由Hibernate来代劳了。由此可见,Hibernate API与JDBC API相比,前者是更加面向对象的数据库访问API。本书第2章会改写本章1.3节的例程1-2的BusinessService类,让它通过Hibernate API来访问数据库。
Hibernate的实现细节不是本书介绍的重点,本书主要介绍如何使用Hibernate。不过,如果想娴熟地使用Hibernate,最好对它的实现细节稍微有所了解。大致说来,Session接口的实现类的save()方法将执行以下步骤:
(1)运用Java反射机制,了解到Monkey对象的类型为Monkey.class。
(2)参考对象-关系映射元数据(Object-Relation Mapping Meta Data),了解到与Monkey类对应的表为MONKEYS表,与Monkey类的name属性对应的字段为NAME字段,依次类推。
(3)根据以上映射信息,生成SQL语句:
insert into MONKEYS(ID,NAME,AGE,GENDER) values(1,'智多星',1,'M');
(4)通过JDBC API来执行以上SQL语句。
由此可见,Hibernate能够把一个Monkey对象保存到关系数据库中,把Monkey对象映射成MONKEYS表中的一条记录。
在以上步骤2中提到了对象-关系映射元数据,它是Hibernate为自己开小灶,要求Java程序必须为自己提供的额外信息,采用XML格式。对象-关系映射元数据存放在对象-关系映射文件中,以hbm.xml作为文件扩展名。如以下例程1-3 的Monkey.hbm.xml文件指定了Monkey类与MONKEYS表的映射关系。
例程1-3 Monkey.hbm.xml
<hibernate-mapping> <class name="mypack.Monkey" table="MONKEYS"> <id name="id" column="ID" type="long"> <generator class="increment"/> </id> <property name="name" column="NAME" type="string" not-null= "true" /> <property name="age" column="AGE" type="int" /> <property name="gender" column="GENDER" type="character"/> </class> </hibernate-mapping>
只要提供了用于映射Monkey类与MONKEYS表的映射文件,Hibernate在运行时就能参照映射文件的信息,把Monkey对象保存到数据库中的MONKEYS表中。
由此可见,如果直接通过JDBC API访问数据库,那么程序中的代码及SQL语句就包含了对象模型与关系数据模型之间的映射关系。如果通过Hibernate API访问数据库,SQL语句就从程序代码中分离出去了,不过,应用程序还需为Hibernate额外提供XML格式的对象-关系映射文件。
要驾驭Hibernate工具,不仅要熟悉它的API中的接口和类的用法,还要掌握如何进行对象-关系映射,从而为Hibernate提供正确的对象-关系映射文件。