持久层是一个应用系统最基本的部份很显然的如果没有持久层所有的工作都将丢失但是对不同的人来说持久层意味着不同的东西持久化时间的长短是选择持久层储存媒介的基本衡量标准之一例如对于生命周期为一个用户会话的数据来说Http session是非常合适的与之对应的跨越多个session或者多个用户的持久化则需要一个数据库来保持数据的数量是另一个非常重要的衡量标准例如最佳实践表明大量的数据最好不要被存储在一个Http会话中在这些情况下你都应该考虑使用数据库在这篇文章中我们的目标就是数据库持久层
你选择的数据库类型对你有架构与设计都有重要的影响作为面向对象的开发人员我们倾向于把数据描绘成描述手上商业问题的一组相互关联的对象—这常被称为域模型 但是最常用的存储媒介是基于关系模型的除非我们的对象模型映射成一个关系结构否则内存中我们数据的表示就会与持久化它的方法不一致这个问题也被称作不对称问题最流行的解决这种不对称问题的是一组被称为对象关系映射工具一个ORM工具是被用来把数据从对象视图转换为关系型提供诸如创建读更新删除(CRUD)等持久性服务的软件有许多的关于ORM工具的论文但是从本质上来说他们谈论的都是对象映射模式最流行的ORM工具是开源的Hibernate工程
在这篇文章中我们展示了如何在一个Struts项目中应用Hibernate另外我们将展示如何建立一个Struts插件来提升你系统的性能
处方
在这个文摘中我们使用一个例子来展示你在struts项目中使用hibernate时所需要的所有东西我们将建立一个应用程序来获取和展示从化学元素周期表里取出的元素这个应用程
序提供给用户一个查找页来通过元素符号来查找元素应用程序将查询数据库里匹配这个元素符号名的记录并返回查找到的元素信息来响应用户请求
首先我们将展示如何启动Hypersonic服务器当数据库服务器启动后我们建立示例程序所需要的表与数据一旦数据库准备运行了我们将建立使用Hypersonic数据库服务器所需的Hibernate的所有东西接下来的步骤是在action里调用Hibernate来处理数据库读取来响应查询请求因为建立Hibernate的Factory对象是非常耗资源的我们建立一个Struts plugin来建立factory并把它保存在context里
让我们从建立Hypersonic数据库服务器开始你需要从下载它放置hsqldbjar在你的classpath路径里从Dos窗口中敲入以下命令来启动Hypersonic:
java orghsqldbServer
虽然不同版本的Hypersonic的服务器响应不同下面的应答是典型的Hypersonic已经准备好响应数据库请求的应答
Server is running
Press [Ctrl]+{c} to abort
随着数据库服务器的启动我们可以建表和填充数据如下列表所示
Listing 建立元素表
create table elements (id integer() IDENTITY
name char()
number char()
mass char()
symbol char());
CREATE UNIQUE INDEX ui_elements_pk ON elements (symbol)insert into elements ( name number mass symbol) values (ManganeseMn);insert into elements ( name number mass symbol) values (ZincZn);insert into elements ( name number mass symbol) values (ThuliumTm);insert into elements ( name number mass symbol) values (CaliforniumCf);insert into elements ( name number mass symbol) values (GoldAu);insert into elements ( name number mass symbol) values (YtterbiumYb);insert into elements ( name number mass symbol) values (MolybdenumMo);insert into elements ( name number mass symbol) values (PalladiumPd);
列表是建立表的SQL语句在symbol列上建立唯一索引插入上面那些化学周期元素当然你也可以从你高校的化学书本里面找出更多的一些数据插入
列表是用来存储从数据库取出数据的JavaBean对象
Listing JavaBean元素
package comstrutsrecipeshibernatebeans;public class Element {
private String name;
private String symbol;
private String number;
private String mass;
private int id;
public Element() {super();
} public Element(String name String symbol String number String mass) {
thisname = name;
thissymbol = symbol;
thisnumber = number;
thismass = mass;
} public int getId() {return id;
} public void setId(int id) {thisid = id;
} public String getMass() {return mass;
} public String getName() {return name;
} public String getNumber() {return number;
} public String getSymbol() {return symbol;
} public void setMass(String mass) {thismass = mass;
} public void setName(String name) {thisname = name;
} public void setNumber(String number) {thisnumber = number;
} public void setSymbol(String symbol) {thissymbol = symbol;
}}
Hibernate是一个对象关系映射工具它的任务是映射对象到关系型表反之亦然所以我们必须告诉Hibernate如何映射列到JavaBean的属性上这个是通过Elementhbmxml文件来完成的这份文件里面包含的信息用来授予Hibernate从表里面拷贝数据到Elements JavaBean的权利如果我们使用Hibernate来更新数据Elementhbmxml文件里的信息将被用来解析从Elements JavaBean来的数据来生成更新的SQL语句列表显示了Elementhbmxml
Listing Elementhbmxml
<?xml version=?><!DOCTYPE hibernatemapping PUBLIC //Hibernate/Hibernate Mapping DTD//EN mappingdtd><hibernatemapping>
<class name=comstrutsrecipeshibernatebeansElement table=elements>
<id name=id column=id>
<generator class=native/>
</id>
<property name=name column=name/>
<property name=number column=number/>
<property name=mass column=mass/>
<property name=symbol column=symbol/>
</class></hibernatemapping>
让我们跳到列表
我们声明了与elements表相联系的类文件的完整的包名然后我们声明了表的名字与这个类相关联接下来我们声明从JavaBean的id属性到表的id列的映射因为property和column属性都有相同的值我们本来可以忽略column属性但是为了清晰起见我们还是把column列出来 <id>是个特殊的标签它被用来声明表的主键闭合的标签<generator>表示Hibernate以最适合数据库实现的方式生成该主键你可以参考Hibernate文档有关标签<id>的更多信息最后我们为其它的JavaBean属性做声明为了清晰起见column属性再次被声明
一旦映射文件被详细的分析那一切都非常的明晰了它简单地声明了表与类的映射和JavaBean属性与表的列名的映射接下来我将告诉你在哪里放置这个文件
接下来我们通过声明环境信息来配置Hibernate在列表我们展示Hibernatecfgxml文件
Listing hibernatecfgxml
<?xml version= encoding=utf?><!DOCTYPE hibernateconfiguration PUBLIC //Hibernate/Hibernate Configuration DTD//EN configurationdtd><hibernateconfiguration>
<sessionfactory>
<property name=dialect>netsfhibernatedialectHSQLDialect</property>
<property name=connectiondriver_class>orghsqldbjdbcDriver</property>
<property name=connectionusername>sa</property> <property name=connectionpassword></property> <property name=connectionurl>jdbc:hsqldb:hsql://</property>
<property name=show_sql> </property> <property name=>true</property>
<mapping resource=/com/strutscookbook/hibernate/beans/Elementhbmxml/></sessionfactory></hibernateconfiguration>
让我们跳到列表
我们以指定数据库实现方言开始允许Hibernate充分利用实现特殊化的属性我们声明Hypersonic方言我们可以参考Hibernate文档以选择数据库相应的方言然后我们声明数据库驱动必须保证这个驱动在应用程序的classpath上然后我们声明数据库的用户名数据库密码连接数据库的URL接下来我们通知Hibernate在日志里显示运行时生成的SQL语句
Hibernatecfgxml文件必须被放在你的classpath里
在你的程序里使用hibernate必须有下面几