Apache Geronimo 以其灵活性和敏捷性成为目前最受欢迎的开源应用服务器之一。Geronimo 集成了许多技术和概念,Apache Tomcat、Apache Derby、Jetty和Apache Axis 等;并对很多框架都提供支持,如 Spring、Tuscany、Hibernate 等。您可以通过 developerworks 的 Apache Geronimo 项目资源中心来更多的了解 Apache Geronimo。
Hibernate 是一个对象关系映射和持久性框架,它允许您用 XML 配置文件把普通 Java 对象映射到关系数据库表。对象和数据的映射使开发人员不需要关心数据库,通过操作数据对象来实现对数据库的操作。您可以在Hibernate的官方网站上查看文档,并下载最新版本 Hibernate。
但是如何将 Java 对象通过 Hibernate 映射到 Geronimo 的内置数据库 Derby 上呢?又如何将这样一个应用系统在 Geronimo 服务器上运行起来呢?下面将通过一个实例做具体介绍。
下面的实例主要实现对客户信息的增删改查。将数据存储在 Apache Derby 数据库上,然后配置 Hibernate 来实现 Java 对象和数据库表的映射,最后实现业务逻辑并将应用部署到 Apache Geronimo 服务器上。您可以下载实例代码,代码可以直接在 Geronimo 上运行,对照代码看这篇文章更直观。
我们首先来创建数据表。Apache Derby 是一个与平台无关的开源数据库,它默认内置在 Apache Geronimo 之中。尽管 Derby 轻量、简单,但其特性丰富,可以支持关系数据库中的所有企业级的特性,包括崩溃恢复、事务回滚和提交、行/表级锁、视图、主键/外键约束、触发器、子查询表达式等。您可以通过 developerworks 的Apache Derby 资源中心来更多的了解 Apache Derby。
管理 Derby 数据库
由于 Derby 只是另外一个 Java 类库,因此它没有自己的管理客户端。我们可以使用任意一个喜欢的DB客户端如 SQL Explorer 等来管理 Derby。对于内置在 Geronimo 中的Derby,我们还可以通过Geronimo的控制台来对 Derby 进行管理。
用 Geronimo 控制台管理Derby数据库,运行 <Geronimo home>/bin/startup.bat 启动Geronimo,然后在地址栏输入http://localhost:8080/console/portal/welcome 进入Geronimo控制台,默认用户名/密码为 system/manager。在控制台上可以选择数据库运行任意 SQL,如图1所示。
创建数据库 SAMPLE
可以在Geronimo控制台上直接创建一个数据库SAMPLE。
创建数据表 CUSTOMER
运行清单1中的DDL来创建 CUSTOMER 数据表,将 ID 设置为自动增长来作为 CUSTOMER表的主键。
(
ID INTEGER NOT NULL PRIMARY KEY GENERATEDALWAYS AS IDENTITY
(START WITH 1 ,INCREMENT BY 1 ),
CUSTNAME VARCHAR ( 35 ) NOT NULL ,
AGE INTEGER ,
EMAIL VARCHAR ( 35 ),
ADDRESS VARCHAR ( 35 ),
CITY VARCHAR ( 35 ),
COUNTRY VARCHAR ( 3 )
)
配置数据库 Derby 的连接
Derby 提供两种部署和连接的方式:
- 嵌入式模式(embedded mode):Derby 只处理来自与应用程序使用的 JVM 相同的 JVM 的请求。在采用嵌入式模式来使用 Derby 时,应用程序会在启动和关闭时分别自动启动或停止关系引擎。使用derby.jar 包中JDBC 驱动程序org.apache.derby.jdbc.EmbeddedDriver。
- 网络服务器模式(network server mode):Derby 会处理来自不同 JVM 的应用程序请求。这时可以使用其他语言如 Perl、PHP、Python 或 C 等来连接,同时也支持网络连接。使用derbyclient.jar 包中JDBC 驱动程序 org.apache.derby.jdbc.ClientDriver。
在本实例中使用嵌入式模式来连接 Derby。如清单2所示,主要配置链接Derby的信息。其中(1)要将connection的URL设置为jdbc:derby:<Geronimo home>/var/derby/<数据库名称>;create=true,create=true 属性说明如果该数据库不存在时,就创建该数据库。
<! DOCTYPEhibernate-configuration
PUBLIC"-//Hibernate/HibernateConfigurationDTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
< hibernate-configuration >
< session-factory >
< property name ="hibernate.connection.url" >
jdbc:derby:D:/geronimo-1.1/var/derby/SAMPLE;create=true </ property >
|(1)
< property name ="hibernate.connection.driver_class" >
org.apache.derby.jdbc.EmbeddedDriver </ property >
< property name ="hibernate.connection.username" > APP </ property >
< property name ="hibernate.connection.password" ></ property >
< property name ="dialect" > org.hibernate.dialect.DerbyDialect </ property >
< property name ="myeclipse.connection.profile" > MyEclipseDerby </ property >
< property name ="connection.password" > myeclipse </ property >
< property name ="connection.driver_class" > org.apache.derby.jdbc.EmbeddedDriver </ property >
< property name ="current_session_context_class" > thread </ property >
</ session-factory >
</ hibernate-configuration >
按照 CUSTOMER 数据表的字段,来创建持久化对象 Customer.java。如清单1中的字段与清单3中的属性名和类型一一对应。
privatestaticfinallongserialVersionUID=1L;
privateintid;
privateStringcustName;
privateintage;
privateStringemail;
privateStringaddress;
privateStringcity;
privateStringcountry;
publicintgetId()...{
returnid;
}
publicvoidsetId(intid)...{
this.id=id;
}
…get…
…set…
}
然后要将对象和数据表的映射关系用描述文件的方式提供给Hibernate。如清单4所示。其中如(1)<generator> 子元素是一个 Java 类的名字,用来为该持久化类的实例生成唯一的标识,我们已经在创建数据表的时候将ID设置为自动增长字段,因此我们可以将 class 设置为identity,这样当创建记录时数据库就会自动为这个地段赋值。
其他属性依照name=对象属性,column=数据表列名的映射编写这一映射描述文件。
清单4. 对象和数据表的映射描述 Customer.hbm.xml
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mappingpackage="com.ibm.sample.bean">
<classname="Customer"table="CUSTOMER"lazy="true">
<comment>customertable</comment>
<idname="id"column="ID"type="int">
<generatorclass="identity"/>|(1)
</id>
<propertyname="custName"column="CUSTNAME"type="string"
update="true"insert="true"/>
<propertyname="age"column="AGE"type="int"
update="true"insert="true"/>
<propertyname="email"column="EMAIL"type="string"
update="true"insert="true"/>
<propertyname="address"column="ADDRESS"type="string"
update="true"insert="true"/>
<propertyname="city"column="CITY"type="string"
update="true"insert="true"/>
<propertyname="country"column="COUNTRY"type="string"
update="true"insert="true"/>
</class>
</hibernate-mapping>
最后要将映射描述文件在 hibernate.cfg.xml 中进行配置,如清单5所示。
清单5. 配置映射描述到 hibernate.cfg.xml
< session-factory >
…………
< mapping resource ="com/ibm/sample/bean/Customer.hbm.xml" />
</ session-factory >
</ hibernate-configuration >
本实例主要实现对客户信息的增删改查,所以业务逻辑方法也主要是这四种,这一般也是对数据最多的操作。
在通过 Hibernate 这一持久层访问数据时,首先要拿到相应配置文件(hibernate.cfg.xml)的SessionFactory,然后打开这个 SessionFactory的Session,我们进行的所有数据操作都会在这个Session中完成,在操作完成后关闭此Session。
创建客户信息
将客户的各个信息设置到 Customer 对象中去,然后调用 Session 的 save 方法,将对象保存到数据库中去。
Stringaddress,Stringcity,Stringcountry) ... {
Sessionsess=HibernateUtil.currentSession();
Transactiontrans=sess.beginTransaction();
Customercustomer=newCustomer();
customer.setCustName(custNanme);
customer.setEmail(email);
customer.setAge(age);
customer.setAddress(address);
customer.setCity(city);
customer.setCountry(country);
sess.save(customer);
trans.commit();
HibernateUtil.closeSession();
}
删除客户信息
要删除一条记录首先要先拿到这条记录的实例,我们用主键ID来取得customer对象,然后调用Session的delete 方法,将数据库中的记录删除。
Sessionsess=HibernateUtil.currentSession();
Transactiontrans=sess.beginTransaction();
Customercustomer=(Customer)sess.load(Customer.class,newInteger(id));
sess.delete(customer);
trans.commit();
HibernateUtil.closeSession();
}
修改客户信息
修改一条记录首先是拿到记录的实例,然后更改实例的属性值,再将修改后的信息保存到数据库中。我们调用 Session 的 update 方法来修改信息。
Stringemail, int age,Stringaddress,Stringcity,Stringcountry) ... {
Sessionsess=HibernateUtil.currentSession();
Transactiontrans=sess.beginTransaction();
Customercustomer=(Customer)sess.load(Customer.class,newInteger(id));
customer.setCustName(custName);
customer.setEmail(email);
customer.setAge(age);
customer.setAddress(address);
customer.setCity(city);
customer.setCountry(country);
sess.update(customer);
trans.commit();
HibernateUtil.closeSession();
}
查询客户信息
在查询客户信息的方法中,主要应用 HibernateSQL 来实现按不同的查询条件查询。如清单9所示,创建了三个查询方法,返回所有客户信息、按客户ID查询和按客户名字查询。其实上面的创建和删除的操作也可以通过 HibernateSQL 来实现,不过上面的方法更简单。
StringqueryString="selectafromCustomerasa";
Sessionsess=HibernateUtil.currentSession();
Transactiontrans=sess.beginTransaction();
Queryquery=sess.createQuery(queryString);
Listlist=query.list();
trans.commit();
HibernateUtil.closeSession();
returnlist;
}
public CustomergetCustomerByID( int id) ... {
StringqueryString="selectcfromCustomerascwherec.id=:cid";
Sessionsess=HibernateUtil.currentSession();
Transactiontrans=sess.beginTransaction();
Queryquery=sess.createQuery(queryString);
query.setParameter("cid",newInteger(id));
Customercustomer=(Customer)sess.load(Customer.class,newInteger(id));
trans.commit();
HibernateUtil.closeSession();
returncustomer;
}
public ListgetCustomerByName(Stringname) ... {
StringqueryString="selectcfromCustomerascwherec.custNamelike:name";
Sessionsess=HibernateUtil.currentSession();
Transactiontrans=sess.beginTransaction();
Queryquery=sess.createQuery(queryString);
query.setParameter("name","%"+name+"%");
Listlist=query.list();
trans.commit();
HibernateUtil.closeSession();
returnlist;
}
创建 Web 页面调用业务方法
最后我们可以 Web 页面来调用上面所创建的业务方法,从而实现在页面对数据进行处理。为了更好更简单的显示数据,在JSP中应用的 DisplayTag 来组织数据显示,您可以在DisplayTag Homepage 得到更多关于 DisplayTag 的详细信息。关于这一部分将不做详细介绍。
这样我们的实例已经创建完成了,最后要将它部署在 Geronimo 服务器上。首先将应用导出成war 文件。然后启动 Geronimo,进入控制台,对 war 文件部署实例。如图2所示。
部署成功以后,通过 http://localhost:8080/HibernateGeronimo/ 访问这个实例,如图3所示。
通过本文,我们向您介绍了如何管理 Apache Derby 数据库;如何集成 Hibernate 和 Apache Derby;如何创建 Hibernate 应用,以及如何将 Web 应用部署到 Geronimo 服务器。
在编写本文实例的过程中,充分体会到 Derby 是一个既简单又复杂的数据库,Derby 的安装和使用都很简单,但是它的功能却很丰富、复杂。特别是它内置在 Geronimo 中,通过页面控制台就能管理 Derby 数据库,这真是一件令人兴奋的事情。
Geronimo 是一个特性非常丰富的轻量级 J2EE 服务器,从控制台我们就能看到它对很多技术和框架提供支持。但是在本文实例中,没有应用到太多特性,希望在以后能与大家分享。
描述 | 名字 | 大小 | 下载方法 |
---|---|---|---|
本文实例 | HibernateGeronimo.war | 6555KB | HTTP |
关于下载方法的信息 |