Jdon应用系统案例开发

jdon官方网站:http://www.jdon.com/jdonframework/app.htm

几乎大部分软件系统都有下面两个基本功能:

  1. 新增/查询/修改/删除(CRUD);
  2. 批量查询和分页显示

本文Step By Step详细讲解如何使用Jdon框架基于领域模型快速开发这两个功能,通过Jdon框架的可以快速完成系统原型(ArcheType),使得开发者将真正精力集中在每个项目系统的特殊业务处理。

本文档源码下载

增删改查(CRUD)和批量分页查询是每个系统的基本功能,下面分这两部分描述。

CRUD开发步骤

说明:每个应用系统中存在大量重复的CRUD开发流程,通过本框架可快速完成这些基本基础工作量,将精力集中在特殊功能设计上。 CRUD快速开发主要简化了表现层的流程,将其固化,或者是模板化,以配置替代代码编制,灵活而快速。每个Model一套固化CRUD流程。

CRUD开发步骤分两个部分:代码编写 、配置。

CRUD代码:

代码只需要三步:
1、域建模:建立sample.model.Message,如下:

public class Message extends Model {
   private Long messageId;
   private String name;

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }

   .......
}

注意点:

  • 模型类Message必须继承框架的com.jdon.controller.model.Model,或者实现com.jdon.controller.model.ModelIF接口。
  • 该模型类必须有一个能够标识其对象唯一性的主键,如messageId,这个主键相当于数据表的主键。

2、建立Model组件服务:首先建立模型Message的服务接口sample.service. MessageService:

public interface MessageService {
   void createMessage(EventModel em);
   void updateMessage(EventModel em);
   void deleteMessage(EventModel em);
   Message getMessage(String messageId);
}

至于MessageService的具体实现子类可以在现在或者以后建立,可见源码包中的sample.service.MessageServiceImp.

3、建立Model的表现层边界模型:sample.web.MessageForm,必须继承框架的ModelForm,如下:

public class MessageForm extends ModelForm {

   private String messageId;
   private String name;

   public String getName() { return name; }
   public void setName(String name) { this.name = name; }
}

表现层MessageForm内容基本上是从业务层模型Message类中拷贝过来的,主要是为了保持MessageForm和Message的字段一致,我们就可以通过框架内MessageForm和Message的相同字段的复制进行数据传送,将业务层的Message数据传送到表现层MessageForm;或将界面表现层MessageForm传送到Message中。

一个模型Message有关CRUD实现的代码工作到此结束,如果有其他模型,完全按照上述三个步骤再做一次,是不是不太费脑筋?有点模板化开发味道?下面谈谈CRUD实现第二组成部分:

CRUD配置:

两个配置文件分别是:

  • 将前面三步编写的类建立关系:jdonframework.xml
  • 配置界面流程:struts-config.xml

一、Jdon框架配置文件

首先我们将前面三步编写的三个类:模型Message、服务MessageService和界面模型MessageForm建立起联系,也就是告诉Jdon框架这三者是解决一个模型增删改查CRUD功能实现的。 由于这个配置文件是告诉Jdon框架的,因此,我们取名为jdonframework.xml,当然你也可以取其他名称,无论取什么名称,都要告诉Jdon框架,在struts-config.xml中配置:

<plug-in className="com.jdon.strutsutil.InitPlugIn">
   <set-property property="modelmapping-config"                            value="jdonframework.xml" />
</plug-in>

jdonframework.xml配置内容如下:


<models>
<!-- the Model class is sample.model.Message, and the primary key of the Model class is messageId -->
   <model key="messageId" class ="sample.model.Message">
      <!-- configuration about UI Form: MessageForm -->
      <actionForm name="messageForm"/>
         <handler>
            <!-- configuration about the Model service : MessageService -->
            <service ref="messageService">
            <getMethod name="getMessage" />
            <createMethod name="createMessage" />
            <updateMethod name="updateMessage" />
            <deleteMethod name="deleteMessage" />
         </service>
       </handler>
   </model>

   ......
</models>
<services>
   <!-- the Ioc configuration about MessageService -->
   <pojoService name="messageService" class="sample.service.MessageServiceImp"/>

   ......
</services>

以上配置是配置模型Message、模型服务MessageService和界面模型MessageForm三者关系的,下面详细说明三个部分的配置:

1、模型Message的配置:
这是通过第一行中的class值来指定当前Model是sample.model.Message:

<model key="messageId" class ="sample.model.Message">

其中,Message模型的主键是messageId,这个messageId必须是Message类的一个字段;同时是用来唯一标识唯一的Message模型对象,也就是Object ID,或者可以认为是模型Message对应的数据表message的主键。

2、界面模型MessageForm配置:

<actionForm name="messageForm"/>

可能你已经注意到:这里并没有写界面模型完整类:sample.web.MessageForm,而好像是MessageForm类的名称messageForm。 那么配置中messageForm名称是从哪里来的呢?是struts-config.xml中ActionForm定义名称,如下:

<struts-config>
   <form-beans>   
      <form-bean name="messageForm"                            type="sample.web.MessageForm" />
      ……
   </form-beans>
…..
</struts-config>

可见我们的界面模型完整类sample.web.MessageForm是在struts-config.xml中form-beans中配置,并且命名为messageForm,而这个messageForm就是jdonframework.xml中的messageForm。

3、模型服务MessageService配置:
在jdonframework.xml中首先申明MessageService完整实现是类sample.service.MessageServiceImp,并且取名为messageService:
<pojoService name="messageService" class="sample.service.MessageServiceImp"/>
这样,我们就可以详细将我们自己编写的messageService的CRUD方法名告诉Jdon框架了:


<handler>
   <!-- this will refer to service: messageService-->   
   <service ref="messageService">

         <!--getMessage is the method name of MessageService -->
         <getMethod name="getMessage" />

         <!--createMessage is the method name of MessageService -->
         <createMethod name="createMessage" />

         <!--updateMessage is the method name of MessageService -->
         <updateMethod name="updateMessage" />

          <!--deleteMessage is the method name of MessageService -->
         <deleteMethod name="deleteMessage" />

      </service>
</handler>

黑体字部分正是messageService所指的类sample.service.MessageServiceImp所继承的接口sample.service. MessageService四个方法,可见前面代码步骤第二步。

二、界面流程配置

界面流程主要是配置CRUD界面流程,Jdon框架CRUD流程主要分两个部分:第一是推出供用户新增修改删除的页面;第二是接受用户提交新增修改过的数据,以便递交到业务层保存。
这部分配置主要是配置struts-config.xml:
1、配置推出CRUD页面流程:


<action name="messageForm" path="/messageAction"          type="com.jdon.strutsutil.ModelViewAction"
         scope="request" validate="false">
                  <forward name="create" path="/message.jsp" />
                  <forward name="edit" path="/message.jsp" />
</action>

其中com.jdon.strutsutil.ModelViewAction是Jdon框架类。只要客户端浏览器调用http://localhost:8080/messageAction.do,通过上述配置将激活forward的name=”create”流程,就能得到一个空白表单的页面message.jsp;如果客户端浏览器调用http://localhost:8080/messageAction.do?action=edit&messageId=18,通过上述配置将激活forward name=”edit”流程,得到一个填满数据的表单页面,供用户修改。

2、配置:接受用户提交新增修改过的数据,以便递交到业务层保存:


<html:form action="/messageSaveAction.do" method="POST" >

<html:hidden property="action"/> <!-- this is a rule -->

MessageId:<html:text property="messageId"/>
<br>Name:<html:text property="name"/>
<br><html:submit property="submit" value="Submit"/>
</html:form>

其实在上一步的message.jsp中已经使用到这一步的配置,在message.jsp的表单action值就是本步配置的path值:/messageSaveAction.do:


<action name="messageForm" path="/messageSaveAction"         type="com.jdon.strutsutil.ModelSaveAction"
        scope="request" validate="true" input="/message.jsp">
                <forward name="success" path="/result.jsp" />
                <forward name="failure" path="/result.jsp" />
</action>

在上面message.jsp中一定要有<html:hidden property="action"/>一行。至此,模型Message的CRUD功能开发完毕。

 

 

批量分页查询实现

批量分页查询开发步骤也分两个部分:代码编写 、配置。

批量查询代码实现:

代码也分三步实现。
1、表现层编写一个查询Action,继承Jdon框架的com.jdon.strutsutil.ModelListAction,该类名称为sample.web. MessageListAction,完成getPageIterator和findModelByKey两个方法。
其中getPageIterator方法内容是业务层MessageService的调用:


MessageService messageService = (MessageService)                                  WebAppUtil.getService("messageService",request);
return messageService.getAllMessages(start, count);

所以MessageService接口中必须有getAllMessages这个方法,主要功能是返回PageIterator对象
findModelByKey方法内容也是业务层MessageService的调用:


MessageService messageService = (MessageService)                                WebAppUtil.getService("messageService", request);
return messageService.getMessage((String)key);

essageService接口中必须有getMessage方法。

2、业务层实现MessageService接口方法getAllMessages内容,一般是直接调用持久层MessageDao方法。

3、持久层实现返回PageIterator对象:


public PageIterator getMessages(int start, int count) throws Exception {
        String GET_ALL_ITEMS_ALLCOUNT =
                "select count(1) from testmessage ";
        String GET_ALL_ITEMS =
               "select messageId from testmessage ";
        return pageIteratorSolver. getPageIterator (GET_ALL_ITEMS_ALLCOUNT, GET_ALL_ITEMS, "",start, count);
}

如果有参数,可以如下查询:


public PageIterator getMessages(Long categoryId, int start, int count) {
       String GET_ALL_ITEMS_ALLCOUNT =
                  "select count(1) from message where categoryId = ? ";
       String GET_ALL_ITEMS =
                   "select messageId from message where categoryId = ? ";
       Collection params = new ArrayList(1);
       params.add(categoryId);//paramters will be put into Collection
       return pageIteratorSolver.getPageIterator(GET_ALL_ITEMS_ALLCOUNT,                                                  GET_ALL_ITEMS, params, start, count);
}

批量查询配置

一、Jdon框架配置文件

本步骤主要是需要告诉jdonframework.xml我们的MessageService实现子类是什么,以及调用的MessageDao等组件,jdonframework.xml如下:


<services>
       <pojoService name="messageService"                               class="sample.service.MessageServiceImp"/>
       <component name="messageDAO"                               class="sample.dao.MessageDAO"/>
       <component name="constants" class="sample.Constants">
              <constructor value="java:/TestDS"/>
       </component>
</services>

因为MessageServiceImp类中调用了MessageDAO,MessageDAO中又涉及JNDI名称,所以它们之间依赖关系靠Jdon框架的IOC容器实现。MessageServiceImp必须有构造器如下:


public class MessageServiceImp implements MessageService{

       private MessageDAO messageDAO;

       public MessageServiceImp(MessageDAO messageDAO){

              this.messageDAO = messageDAO;

       }

}

二、界面流程配置

这一步主要是struts-config.xml配置,和通常struts的ActionForm和Action配置类似:


<form-beans>
……
<form-bean name="listForm" type="com.jdon.strutsutil.ModelListForm" />
</form-beans>

其中com.jdon.strutsutil.ModelListForm是框架批量查询特别使用的类。


<action name="listForm" path="/messageListAction"
       type="sample.web.MessageListAction" scope="request">
              <forward name="success" path="/messageList.jsp" />
</action>

其中sample.web.MessageListAction是我们前面代码编写部分编写的代码。这样,客户端浏览器通过http://localhost:8080/ messageListAction.do就可以实现所有Message批量分页查询显示。
注意,messageList.jsp中编码和通常Struts的Jsp编码是一样的,需要使用logic:iterator从ActionForm为listForm的list字段中获取单个的Message对象,然后显示这些单个Message对象,,如下:


<logic:iterate indexId="i" id="message" name="listForm" property="list" >

       <bean:write name="message" property="name" />

       .........

</logic:iterate

在messageList.jsp中加入下面标签库可以自动显示多页,缺省一个页面显示30个条目。


<MultiPages:pager actionFormName="listForm"       page="/messageListAction.do">

       <MultiPages:prev name="[Prev ]" />
       <MultiPages:index displayCount="1" />
       <MultiPages:next name="[Next ]" />
</MultiPages:pager>

模型Message的批量查询功能已经全部完成。

 

以上是介绍基于开源Jdon框架开发软件系统中的CRUD和批量查询功能步骤,遵循模板化开发,开发人员使用起来轻松而不容易出错,适合软件生产和严格的项目管理。