alartin's profileWindows Live 共享空间PhotosBlogListsMore ![]() | Help |
|
January 10 JBoss Seam: Seam应用框架Seam Application Framework, 听起来挺吓人的,也很容易让人犯糊涂,Seam本身不就是个Web框架么,那里来的应用框架. 其实称之为Seam Component Template Framework更加合适. Seam 组件模板框架. 原因很简单, 这个名词看起来吓人,其实就干一件事情, 把Seam组件开发再简化(尽管通过注释等方法, 开发Seam组件非常简单了). 怎么再简化呢? 大家可以想一想Struts的Dynamic Action历史就明白了. 也就是通过配置来创建基本的Seam组件, 你可以不用写类了! 在componets.xml文件中配置.例如下面的配置信息能够创建一个基本的实现CRUD功能的Seam组件: <framework:entity-home name="personHome"
entity-class="eg.Person"
entity-manager="#{personDatabase}">
<framework:id>#{param.personId}</framework:id>
</framework:entity-home>如果你讨厌通过XML配置来替代编程的话(反正我讨厌), 你也可以通过类继承来实现: @Stateful
@Name("personHome")
public class PersonHome extends EntityHome<Person> implements LocalPersonHome {
@RequestParameter String personId;
@In EntityManager personDatabase;
public Object getId() { return personId; }
public EntityManager getEntityManager() { return personDatabase; }
}
一头雾水吧?让我们看看Seam的代码.所有的Application Framework代码位于org.jboss.seam.framework下面. 最重要的两个类为Home类和Query类. Home类: 提供了实体类的持久化操作CRUD. Seam提供两种实现:EntityHome和HibernateEntityHome. 一个是给JPA的,一个是给Hibernate的. Query类: 顾名思义,提供实体类查询的.同样,Seam提供两种实现: EntityQuery, HibernateEntityQuery.一个是给JPA的,一个是给Hibernate的. Home类和Query类天生就能和会话范围,事件范围和对话范围一起工作. 需要注意的是:Seam Application Framework只能和Seam管理的持久化上下文一起工作,Seam-managed Persistence Context. 默认的情况下,Application Framework的组件查找一个名为entityManager的持久化上下文. 来点仔细的. 我们看一下Home, 其实Home就是给某个实体类干CRUD活的,类似于EJB3的Session Bean, 比如说我们有个实体类Person, 那么PersonHome就是创建,修改,删除Person的工具么. @Entity
public class Person { // 这个是我们的实体类
@Id private Long id;
private String firstName;
private String lastName;
private Country nationality;
//getters and setters...
}1. 可以通过在components.xml配置相对应的Home类: <framework:entity-home name="personHome" entity-class="eg.Person" /> 2. 或者自己写类来继承 @Name("personHome")
public class PersonHome extends EntityHome<Person> {} // 参数是实体类啊
反正我觉的第二种方法最合适,如果你是个程序员的话. 然后你就自动获得PersonHome类了, 内置persist(), remove(), update()和getInstance()方法. 酷吧!当然,你要调用remove()或update()方法前,要先设置setId(Object id)方法. OK, 那么怎么使用呢, 我们看一个例子, 我们可以直接在页面上使用Home类: <h1>Create Person</h1>
<h:form>
<div>First name: <h:inputText value="#{personHome.instance.firstName}"/></div>
<div>Last name: <h:inputText value="#{personHome.instance.lastName}"/></div>
<div>
<h:commandButton value="Create Person" action="#{personHome.persist}"/>
</div>
</h:form>
用户在页面上的输入直接就能创建一个Person实体对象了,当然,通过PersonHome创建的.不过我们会觉得使用personHome.instance很不爽, 其实我们更加愿意使用person来代替它. 做到这一点也很容易: 1. 在components.xml中配置 <factory name="person"
value="#{personHome.instance}"/>
<framework:entity-home name="personHome"
entity-class="eg.Person" />2.在自己写的类中加一个方法,然后用@Factory注释 @Name("personHome")
public class PersonHome extends EntityHome<Person> {
// 很简单,这个方法仅仅调用的getInstance()而已
@Factory("person")
public Person initPerson() { return getInstance(); }
}OK, 现在我们的页面就可以变成: <h1>Create Person</h1>
<h:form>
<div>First name: <h:inputText value="#{person.firstName}"/></div>
<div>Last name: <h:inputText value="#{person.lastName}"/></div>
<div> // 这里没变
<h:commandButton value="Create Person" action="#{personHome.persist}"/>
</div>
</h:form>相信你已经很满意了吧.那么,也许你想搞个页面来编辑某个已经持久化的Person实体,那么你需要在pages.xml中配置页面参数: <pages>
<page view-id="/editPerson.jsp"> // 编辑页面需要person id参数
<param name="personId" value="#{personHome.id}"/>
</page>
</pages>让我们看看编辑页面: <h1> // 如果personHome还没有管理某个person实体的话, 页面显示为 创建Person, 否则显示 编辑Person // 此时,页面参数personId 为空
<h:outputText rendered="#{!personHome.managed}" value="Create Person"/>
<h:outputText rendered="#{personHome.managed}" value="Edit Person"/>
</h1>
<h:form>
<div>First name: <h:inputText value="#{person.firstName}"/></div>
<div>Last name: <h:inputText value="#{person.lastName}"/></div>
<div>//如果personHome还没有管理某个person实体的话,按钮显示创建,否则的话显示两个按钮 更新和删除 // 此时,页面参数personId 为空
<h:commandButton value="Create Person" action="#{personHome.persist}" rendered="#{!personHome.managed}"/>
<h:commandButton value="Update Person" action="#{personHome.update}" rendered="#{personHome.managed}"/>
<h:commandButton value="Delete Person" action="#{personHome.remove}" rendered="#{personHome.managed}"/>
</div>
</h:form>关于Home类,我们先讲这么多,再来看看Query类. Query类通常用来查询一个实体对象的列表.比如获得所有Person: 1.通过components.xml配置 <framework:entity-query name="people"
ejbql="select p from Person p"/>使用页面: <h1>List of people</h1>
<h:dataTable value="#{people.resultList}" var="person">
<h:column>
<s:link view="/editPerson.jsp" value="#{person.firstName} #{person.lastName}">
<f:param name="personId" value="#{person.id}"/>
</s:link>
</h:column>
</h:dataTable>要是我们想分页看呢: <framework:entity-query name="people"
ejbql="select p from Person p"
order="lastName" // 排序
max-results="20"/> // 分页最大结果在pages.xml配置: <pages>
<page view-id="/searchPerson.jsp">
<param name="firstResult" value="#{people.firstResult}"/>
</page>
</pages>更改后的页面: <h1>Search for people</h1>
<h:dataTable value="#{people.resultList}" var="person">
<h:column>
<s:link view="/editPerson.jsp" value="#{person.firstName} #{person.lastName}">
<f:param name="personId" value="#{person.id}"/>
</s:link>
</h:column>
</h:dataTable>
<s:link view="/search.xhtml" rendered="#{people.previousExists}" value="First Page">
<f:param name="firstResult" value="0"/> // <<
</s:link>
<s:link view="/search.xhtml" rendered="#{people.previousExists}" value="Previous Page">
<f:param name="firstResult" value="#{people.previousFirstResult}"/>
</s:link>
<s:link view="/search.xhtml" rendered="#{people.nextExists}" value="Next Page">
<f:param name="firstResult" value="#{people.nextFirstResult}"/>
</s:link>
<s:link view="/search.xhtml" rendered="#{people.nextExists}" value="Last Page">
<f:param name="firstResult" value="#{people.lastFirstResult}"/>
</s:link>我们甚至可以监听一些事件,例如更新,删除等等然后根据这些事件,刷新查询: <event type="org.jboss.seam.afterTransactionSuccess">
<action execute="#{people.refresh}" />
</event>甚至可以限定是Person实体的事件: <event type="org.jboss.seam.afterTransactionSuccess.Person">
<action execute="#{people.refresh}" />
</event>
需要注意的是:上面的Query例子都用的是配置形式,你也可以写自己的类来继承.Seam通常将Query的继承类命名为XXXList, 将Home类命名为XXXHome, 其中XXX是实体类. 有趣的Controller类其实就是一些实体类的帮助类,让你更加容易使用内置组件和内置组件的方法. like session bean | like session bean XXXList/Query(负责XXX的查询) <---- 你的实体类XXX ----> XXXHome (负责XXX的CRUD工作) | Controller(XXX的帮助类) Comments (1)
Trackbacks (1)The trackback URL for this entry is: http://alarnan.spaces.live.com/blog/cns!819CBC613DE169EF!170.trak Weblogs that reference this entry
|
|
|