结合Hibernate使用Tapestry

来源:互联网 发布:模拟退火算法实例 编辑:程序博客网 时间:2024/05/20 03:46

填写完表单,提交成功(在没有错误的情况下):你又回到了当前页面,所有的文本域置为空。发生了什么,数据去哪里了?

在表单提交成功后(没有错误的提交),我们还没有告诉Tapestry去做什么。Tapestry默认刷新当前页面,新的请求会有一个新的实例对象Address被创建(所以文本框为空)。

那么,当我们创建对象时,也许我们需要保存到某个地方...数据库. 我们以 对象/关系 映射的方式来快速结合Tapestry和 Hibernate  然后存储数据到数据库 HyperSQL (HSQLDB)。HSQLDB 是是一种植入数据库,不需要安装--会作为Maven依赖。

重新配置项目

本项目我们使用Hibernate和HSQLDB的Tapestry,前端使用bootrap。

更新依赖

首先, 我们必须要更新 POM 里面的依赖,包含 Hibernate, Tapestry/Hibernate 结合库 以及 HSQLDB JDBC 驱动:

src/pom.xml (partial)
<dependencies>
 
    <dependency>
        <groupId>org.apache.tapestry</groupId>
        <artifactId>tapestry-hibernate</artifactId>
        <version>${tapestry-release-version}</version>
    </dependency>
 
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>2.3.2</version>
    </dependency>
    ...
</dependencies>

Tapestry-hibernate 库作为传递依赖包含Hibernate和Tapestry-core。这就是说你只需要在<artifactId>元素用"tapestry-core"替换 "tapestry-hibernate".

修改并保存POM,Maven会自动加载依赖jar包。

Hibernate 配置

Hibernate 需要一个配置文件 hibernate.cfg.xml, 通常用来存储连接和其它信息.在 src/main/resources 下创建它吧:

src/main/resources/hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <propertyname="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <propertyname="hibernate.connection.url">jdbc:hsqldb:./target/work/t5_tutorial1;shutdown=true</property>
        <propertyname="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <propertyname="hibernate.connection.username">sa</property>
        <propertyname="hibernate.connection.password"></property>
        <propertyname="hbm2ddl.auto">update</property>
        <propertyname="hibernate.show_sql">true</property>
        <propertyname="hibernate.format_sql">true</property>
    </session-factory>
</hibernate-configuration>

大部分配置都是定义JDBC驱动和连接地址。

注意连接地址。我们使用的是HSQLDB来保存数据库文件。当关闭应用时我们也会清除HSQLDB的所有数据。就是说项目在使用期间,所有的数据都是持久化的,一旦项目被销毁(比如执行"man clean"),数据内容将全部丢失。

此外,我们配置了Hibernate 更新数据库 schema(概要?),当Hibernate初始化时,它就会被创建,甚至会根据实体类来改变表结构。最后,我们配置了Hibernate输出sql语句,对于初始化一个应用时,这会非常有用。

实体类怎么使用呢?一般情况下,实体类会在hibernate.cfg.xml里配置,但是在Tapestry里是不需要这样做的。可以简单的配置。Tapestry 把实体类都放在了entities包内(本例com.example.tutorial1.entities)并添加了配置。目前我们只有Address类。

添加 Hibernate 注解

对于一个使用Hibernate的实体类,需要添加一些注解。

下面是更新后的 Address 类,添加了Hibernate注解 (包含了Tapestry).

src/main/java/com/example/tutorial/entities/Address.java
packagecom.example.tutorial1.entities;
 
importjavax.persistence.Entity;
importjavax.persistence.GeneratedValue;
importjavax.persistence.GenerationType;
importjavax.persistence.Id;
 
importorg.apache.tapestry5.beaneditor.NonVisual;
importorg.apache.tapestry5.beaneditor.Validate;
 
importcom.example.tutorial1.data.Honorific;
 
@Entity
publicclassAddress
{
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @NonVisual
  publicLong id;
 
  publicHonorific honorific;
 
  @Validate("required")
  publicString firstName;
 
  @Validate("required")
  publicString lastName;
 
  publicString street1;
 
  publicString street2;
 
  @Validate("required")
  publicString city;
 
  @Validate("required")
  publicString state;
 
  @Validate("required,regexp")
  publicString zip;
 
  publicString email;
 
  publicString phone;
}

Tapestry 注解, @NonVisual 和 @Validate, 可以使用在 setter 或 getter 方法 或一个属性上 (就像这里). Hibernate 注解添加到需要的属性上,属性名称会自动匹配。

  • @NonVisual – 一个属性,比如主键,对用户不可见。
  • @Validate – 定义校验属性规则

现在重启你的应用吧。

更新数据库

我们有了设置好的数据库,配置了Hibernate来连接上它。让我们把Address对象存到数据库吧!

提交表单时,我们需要一些代码来执行。当一个Tapestry表单提交时,会有一系列的事件被触发。我们只关心 "success"事件(后面我们会讲到):所有的值会从request中提取到页面属性中,所有的服务端校验完毕后。

success 事件只会在通过校验的情况下触发。

触发事件需要做两件事:

  • 使用Hibernate Session 对象持久化一个新的Address 对象.
  • 提交事务来写入数据库数据

更新 CreateAddress.java 类:

src/main/java/com/example/tutorial/pages/address/CreateAddress.java
packagecom.example.tutorial1.pages.address;
 
importcom.example.tutorial1.entities.Address;
importcom.example.tutorial1.pages.Index;
importorg.apache.tapestry5.annotations.InjectPage;
importorg.apache.tapestry5.annotations.Property;
importorg.apache.tapestry5.hibernate.annotations.CommitAfter;
importorg.apache.tapestry5.ioc.annotations.Inject;
importorg.hibernate.Session;
 
publicclassCreateAddress
{
    @Property
    privateAddress address;
 
    @Inject
    privateSession session;
 
    @InjectPage
    privateIndex index;
 
    @CommitAfter
    Object onSuccess()
    {
        session.persist(address);
 
        returnindex;
    }
}

Inject 注解告诉 Tapestry 注入一个 service ; Tapestry 包含了复杂的IOC容器 (很多方面和Spring相似) ,使用service类型而非字符串ID是很方便的。在任何情况下,Hibernate Session 对象暴露在Tapestry IoC service下,可以被注入(由Tapestry-hibernate模型封装)。

Tapestry 自动开始事务处理;但是默认情况下,请求结束时事务停止。如果我们改变持久化对象,比如添加新地址,需要提交事务。

 CommitAfter 注解 可以应用到任何方法。如果方法正常完成,事务会被提交(新的事务会启动并替代已提交的事务对象).

在持久化新地址对象后,返回应用首页。

注意: 在真实应用中,直接使用Hibernate Session 包含页面和组件是很罕见的。通常情况下,使用数据访问对象来执行常见的操作和查询是较好的方式。

展示地址

看下我们要做的东西,在首页展示所有用户新建的地址。新建一些地址,你会看到类似下面的页面:

在首页添加表格

如何实现上面的效果呢?我们使用 Grid 组件来完成。

Grid 组件像BeanEditForm组件一样,可以使用bean对象。列可排序,当记录超过一页时,会自动添加分页导航。

简单的 Grid 非常容易添加到模板。在Index.tml底部添加如下代码:

src/main/webapp/Index.tml (局部代码)
<t:gridsource="addresses"include="honorific,firstName,lastName,street1,city,state,zip,phone"/>

注意 Grid组件接受和BeanEditForm一样的参数。这里我们使用内部参数来指定展示属性和排序。

现在我们需要做的只是在Java代码里提供地址属性。这里是Index.java代码:

src/main/java/com/example/tutorial/pages/Index.java
packagecom.example.tutorial1.pages;
importjava.util.List;
importorg.apache.tapestry5.ioc.annotations.Inject;
importorg.hibernate.Session;
importcom.example.tutorial1.entities.Address;
public class Index
{
    @Inject
    privateSession session;
    publicList<Address> getAddresses()
    {
        returnsession.createCriteria(Address.class).list();
    }
}

我们使用了 Hibernate Session 对象来查找数据库所有的Address对象。稍后我们来组织较大的结果集。

接下来

我们有许多要讲:更多的组件,更多的自定义,支持AJAX,常见的设计和实现模式,甚至自己写组件(非常容易)

在 Documentation 页查找更多的Tapestry资源, 包含 快速开始  ,快速问答 页面 和指导书. 确认你查看 用户向导, 这里几乎涵盖了所有Tapestry的所有详细讨论。最后,访问(记得收藏) Tapestry JumpStart, 这里提供了一系列详细的教程。

0 0