Jdon框架开发指南
Jdon框架快速开发指南
开发主要步骤如下:
- JdonFramework6.0以上两步开发见这里。
- 快速配置指南
- 新增/查询/修改/删除(CRUD);
- 批量查询和分页显示
本文Step By Step详细讲解如何使用Jdon框架基于领域模型快速开发这两个功能,通过Jdon框架的可以快速完成系统原型(ArcheType),使得开发者将真正精力集中在每个项目系统的特殊业务处理。
快速配置指南
Jdon框架有一个配置文件叫jdonframework.xml,其中配置的是我们编写的Java类,格式如下:
<pojoService name="给自己类取的名称" class="完整类的名称"/>
配置有两个基本项:name和class,class中写全POJO的全名;name是供代码中调用这个服务的名称。
或者使用Annotation注解@Service或@Component,就无需上面这个配置。
假如我们编写了一个类TestServicePOJOImp,代码简要如下:
//@Service("testService") private JdbcDAO jdbcDao; public TestServicePOJOImp(JdbcDAO jdbcDao) { public void createUser(EventModel em) { 接口TestService代码: public interface TestService { void createUser(EventModel em); } |
上面TestServicePOJOImp代码创建完成后,下面有两个并行步骤:
1. 如果在TestServicePOJOImp类前加上@Service注解,就可以了,无需再XML配置。
2.如果你为了更加松耦合,在未来更换类时,不再重新编译源码,那么可以采取XML配置这个步骤,我们在源码目录需要创建一个叫jdonframework.xml配置文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> |
这样,在servlet或jsp或struts的action等客户端代码中,我们可以使用如下代码调用TestServicePOJOImp,注意:以下代码没有具体TestServicePOJOImp类:
TestService testService = (TestService) WebAppUtil.getService("testService ", request); |
以上步骤,只是简单展示框架的一个简要步骤,你可能没有觉得多了一个jdonframework.xml以后,好像比平常代码没什么不同,关键是:如果我们需要使用AnotherTestServicePOJOImp更换原来的TestServicePOJOImp类,只需要更改jdonframework.xml文件,而无须更改客户端代码,也无须重新编译项目了。
当然,还有另外一个优点,就是Ioc/DI依赖注射,细心的人已经注意到TestServicePOJOImp有一个构造参数如下:
public TestServicePOJOImp(JdbcDAO jdbcDao) {
this.jdbcDao = jdbcDao;
}
如果不传入JdbcDAO实例,我们如何能在客户端代码中直接创建TestServicePOJOImp实例呢?原来只要我们在jdonframework.xml中再配置一个JdbcDAO类,概时框架就会自动帮我们创建JdbcDAO实例,并且传入TestServicePOJOImp实例中。
新的jdonframework.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- 新增加的配置:jdbcDAO是被TestServiceImp调用的,是为其服务的。 --> |
再进一步,如果我们经常遇到一些类中需要一些常量或参数定义,那么可以使用如下配置:
<component name="jdbcDAO" class="com.jdon.framework.test.dao.JdbcDAO"> |
这时,要求JdbcDAO构造参数有一个字符串和参数,这样constructor的值java:/TestDS就在JdbcDAO被创建时注射到它的实例中。 JdbcDAO代码如下:
public class JdbcDAO{
......
public JdbcDAO(String jndiName){
System.out.println("jndiname" = jndiName);
......
}
......
}
原来图如下(图中UserReposotoryInMEN相当于JdbcDAO HellpServiceImp相当于TestServicePOJOImp):
启动Jdon框架
有了jdonframework.xml,我们需要在项目中启动它,有两种启动方式:一个是结合struts的struts-config.xml配置方式;另外一个是不结合struts的web.xml配置方式。
第一:web.xml配置方式:
如果你不使用Struts,可以通过web.xml下列配置来启动Jdon框架。
<context-param> |
上述param-value可以配置多个配置,中间以逗号隔开,如下:
<context-param> |
第二:结合struts配置方式(需要struts基础知识):
在struts-config.xml中配置Plugin实现子类:
<plug-in className="com.jdon.strutsutil.InitPlugIn"> |
增删改查(CRUD)和批量分页查询是每个系统的基本功能,下面分这两部分描述。
CRUD开发步骤
说明:每个应用系统中存在大量重复的CRUD开发流程,通过本框架可快速完成这些基本基础工作量,将精力集中在特殊功能设计上。 CRUD快速开发主要简化了表现层的流程,将其固化,或者是模板化,以配置替代代码编制,灵活而快速。每个Model一套固化CRUD流程。
CRUD开发步骤分两个部分:代码编写 、配置。
CRUD代码:
代码只需要三步:
1、域建模:建立UserTest类如下:
//@Model
public class UserTest extends Model {
private String userId;
private String name;public String getName() { return name; }
public void setName(String name) { this.name = name; }.......
}注意点:
- 模型必须以@Model标注
- 或者继承框架的com.jdon.controller.model.Model,或者实现com.jdon.controller.model.ModelIF接口。
- 该模型类必须有一个能够标识其对象唯一性的主键,如userId,这个主键相当于数据表的主键,这个规定符合Evans DDD规定。
为了激活 Domain Model的对象实例驻留内存缓存中,在持久层模型类创建时,加入下面标注:
@Component()
@Introduce("modelCache")
public class UserDAOJdbc implements UserRepository{@Around
public UserTest getUser(String Id) {...... //fetch from key-value stores or relation DB
}
}
DCI:数据Data, 场景Context, 交互Interactions是由MVC发明者Trygve Reenskaug发明的。 见 DCI架构是什么?DCI让我们的核心模型更加简单,只有数据和基本行为。业务逻辑等交互行为在角色模型中 在运行时的场景,将角色的交互行为注射到数据中。
JdonFramework的Domain Events是DCI的交互行为,在实现领域事件的同时也实现了DCI。
为更清楚说明DCI,下面以JdonFramework案例说明。
领域模型是DCI的Data,只有数据和基本行为,更简单,但注意不是只有setter/getter的贫血模型。如下:
@Model
public class UserModel {private String userId;
private String name;@Inject
private ComputerRole computerRole;Domain Events事件或消息的生产者也就是DCI中的角色Role,比如我们有一个专门进行计数计算的角色,实际上真正计算核心因为要使用关系数据库等底层技术架构,并不真正在此实现,而是依托消息消费者@Consumer实现,那么消息生产者可以看出是一个接口,消费者看成是接口的实现:
@Introduce("message")
public class ComputerRole {@Send("computeCount")
public DomainMessage computeCount(UserModel user) {
return new DomainMessage(user);
}@Send("saveUser")
public DomainMessage save(UserModel user) {
return new DomainMessage(user);
}}
DCI第三个元素是场景Context,在这个场景下,ComputeRole将被注入到模型UserModel中,实现计数计算的业务功能:
public class ComputeContext {
private DomainMessage ageAsyncResult;
public void preloadData(UserModel user) {
if (ageAsyncResult == null)
ageAsyncResult = user.getUserDomainEvents().computeCount(user);
}public int loadCountNow(UserModel user) {
preloadData(user);
return (Integer) ageAsyncResult.getEventResult();
}public int loadCountByAsync(UserModel user) {
if (ageAsyncResult == null)
ageAsyncResult = user.getUserDomainEvents().computeCount(user);
else if (ageAsyncResult != null)
return (Integer) ageAsyncResult.getEventResult();
return -1;}
}
2、建立Model组件服务:首先建立模型的服务接口TestService:
public interface TestService {
void createUser(EventModel em);
void updateUser(EventModel em);
void deleteUser(EventModel em);
UserTest getUser(String userId);
}至于TestService的具体实现子类可以在现在或者以后建立
3、建立Model的表现层边界模型UserActionForm,必须继承框架的ModelForm,如下:
public class UserActionForm extends ModelForm {
private String userId;
private String name;public String getName() { return name; }
public void setName(String name) { this.name = name; }....
}表现层UserActionForm内容基本上是从业务层模型UserTest类中拷贝过来的,属于界面对象,用来显示或录入数据。
一个模型的CRUD实现的代码工作到此结束,如果有其他模型,完全按照上述三个步骤再做一次,是不是不太费脑筋?有点模板化开发味道?下面谈谈CRUD实现第二组成部分
CRUD配置:
两个配置文件分别是:
- 将前面三步编写的类建立关系:jdonframework.xml
- 配置界面流程:struts-config.xml
一、Jdon框架配置文件
首先我们将前面三步编写的三个类:模型UserTest、服务TestService和界面模型UserActionForm建立起联系,也就是告诉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>
<model key="userId"
class ="com.jdon.framework.test.model.UserTest">
<!-- configuration about UI Form: UserActionForm -->
<actionForm name="userActionForm"/>
<handler>
<!-- configuration about the Model service : TestService -->
<service ref="testService">
<getMethod name="getUser" />
<createMethod name="createUser" />
<updateMethod name="updateUser" />
<deleteMethod name="deleteUser" />
</service>
</handler>
</model>......
</models>
<services>
<!-- the Ioc configuration about TestService -->
<pojoService name="testService"
class="com.jdon.framework.test.service.TestServicePOJOImp"/>......
</services>以上配置是配置模型UserTest、模型服务TestService和界面模型UserActionForm三者关系的,下面详细说明三个部分的配置:
1、模型UserTest的配置:
这是通过第一行中的class值来指定当前Model是com.jdon.framework.test.model.UserTest:
<model key="userId" class ="com.jdon.framework.test.model.UserTest">
其中,UserTest模型的主键是userId,这个userId必须是UserTest类的一个字段;同时是用来唯一标识唯一的UserTest模型对象,也就是Object ID,或者可以认为是模型UserTest对应的数据表的主键。
2、界面模型UserActionForm配置:
<actionForm name="userActionForm"/>
可能你已经注意到:这里并没有写界面模型完整类:com.jdon.framework.test.web.UserActionForm, 那么配置中userActionForm名称是从哪里来的呢?是struts-config.xml中ActionForm定义名称,如下:
<struts-config>
<form-beans>
<form-bean name="userActionForm" type="com.jdon.framework.test.web.UserActionForm" />
……
</form-beans>
…..
</struts-config>可见我们的界面模型完整类com.jdon.framework.test.web.UserActionForm是在struts-config.xml中form-beans中配置,并且命名为userActionForm,而这个userActionForm就是jdonframework.xml中的userActionForm。
3、模型服务TestService配置:
在jdonframework.xml中首先申明TestService完整实现是类com.jdon.framework.test.service.TestServicePOJOImp,并且取名为testService:
<pojoService name="testService" class="com.jdon.framework.test.service.TestServicePOJOImp"/>
这样,我们就可以详细将我们自己编写的testService的CRUD方法名告诉Jdon框架了:
<handler>
<!-- this will refer to service: testService-->
<service ref="testService"><!--getUser is the method name of testService -->
<getMethod name="getUser" /><!--createUser is the method name of testService -->
<createMethod name="createUser" /><!--updateUser is the method name of testService -->
<updateMethod name="updateUser" /><!--deleteUser is the method name of testService -->
<deleteMethod name="deleteUser" /></service>
</handler>黑体字部分正是testService所指的接口TestService四个方法,可见前面代码步骤第二步。
二、界面流程配置
界面流程主要是配置CRUD界面流程,Jdon框架CRUD流程主要分两个部分:第一是推出供用户新增修改删除的页面;第二是接受用户提交新增修改过的数据,以便递交到业务层保存。
这部分配置主要是配置struts-config.xml:
1、配置推出CRUD页面流程:
<action name="userActionForm" path="/userAction" type="com.jdon.strutsutil.ModelViewAction"
scope="request" validate="false">
<forward name="create" path="/user.jsp" />
<forward name="edit" path="/user.jsp" />
</action>其中com.jdon.strutsutil.ModelViewAction是Jdon框架类。只要客户端浏览器调用http://localhost:8080/userAction.do,通过上述配置将激活forward的name=”create”流程,就能得到一个空白表单的页面user.jsp;如果客户端浏览器调用http://localhost:8080/userAction.do?action=edit&userId=18,通过上述配置将激活forward name=”edit”流程,得到一个填满数据的表单页面,供用户修改。
2、配置:接受用户提交新增修改过的数据,以便递交到业务层保存:
<html:form action="/userSaveAction.do" method="POST" >
<html:hidden property="action"/> <!-- this is a rule -->
userId:<html:text property="userId"/>
<br>Name:<html:text property="name"/>
<br><html:submit property="submit" value="Submit"/>
</html:form>其实在上一步的user.jsp中已经使用到这一步的配置,在user.jsp的表单action值就是本步配置的path值:/userSaveAction.do:
<action name="userForm" path="/userSaveAction" type="com.jdon.strutsutil.ModelSaveAction"
scope="request" validate="true" input="/user.jsp">
<forward name="success" path="/result.jsp" />
<forward name="failure" path="/result.jsp" />
</action>在上面user.jsp中一定要有<html:hidden property="action"/>一行。至此,模型UserTest的CRUD功能开发完毕。
批量分页查询实现
批量分页查询开发步骤也分两个部分:代码编写 、配置。
批量查询代码实现:
代码也分三步实现。
1、表现层编写一个查询Action,继承Jdon框架的com.jdon.strutsutil.ModelListAction,该类名称为com.jdon.framework.test.web.UserListAction,完成getPageIterator和findModelByKey两个方法。
其中getPageIterator方法内容是业务层TestService的调用:
TestService testService = (TestService) WebAppUtil.getService("testService",request);
return testService.getAllUsers(start, count);所以TestService接口中必须有getAllUsers这个方法,主要功能是返回PageIterator对象
findModelByKey方法内容也是业务层TestService的调用:
TestService testService = (TestService) WebAppUtil.getService("testService", request);
return testService.getUser((String)key);TestService接口中必须有getUser方法。
2、业务层实现TestService接口方法getAllUsers内容,一般是直接调用持久层JdbcDao方法。
3、持久层实现返回PageIterator对象:
public PageIterator getUsers(int start, int count) throws Exception {
String GET_ALL_ITEMS_ALLCOUNT =
"select count(1) from usertest ";//usertest是数据表名
String GET_ALL_ITEMS =
"select userId from usertest ";//usertest是数据表名
return pageIteratorSolver. getPageIterator (GET_ALL_ITEMS_ALLCOUNT, GET_ALL_ITEMS, "",start, count);
}如果有参数,可以如下查询:
public PageIterator getUsers(Long categoryId, int start, int count) {
String GET_ALL_ITEMS_ALLCOUNT =
"select count(1) from usertest where categoryId = ? ";
String GET_ALL_ITEMS =
"select userId from usertest 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我们的TestService实现子类是什么,以及调用的JdbcDao等组件,jdonframework.xml如下:
<services>
<pojoService name="testService" class="com.jdon.framework.test.service.TestServicePOJOImp"/>
<component name="jdbcDAO" class="com.jdon.framework.test.dao.JdbcDAO"/>
<component name="constants" class="com.jdon.framework.test.Constants">
<constructor value="java:/TestDS"/>
</component>
</services>因为TestServicePOJOImp类中调用了JdbcDAO,JdbcDAO中又涉及JNDI名称,所以它们之间依赖关系靠Jdon框架的IOC容器实现。TestServicePOJOImp必须有构造器如下:
public class TestServicePOJOImp implementsTestService{
private JdbcDAO jdbcDAO;
public TestServicePOJOImp(JdbcDAO jdbcDAO){
this.jdbcDAO = jdbcDAO;
}
}
二、界面流程配置
这一步主要是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="/userListAction"
type="com.jdon.framework.test.web.UserListAction"
scope="request">
<forward name="success" path="/userList.jsp" />
</action>其中UserListAction是我们前面代码编写部分编写的代码。这样,客户端浏览器通过http://localhost:8080/userListAction.do就可以实现所有UserTest批量分页查询显示。
注意,userList.jsp中编码和通常Struts的Jsp编码是一样的,需要使用logic:iterator从ActionForm为listForm的list字段中获取单个的UserTest对象,然后显示这些单个UserTest对象,,如下:
<logic:iterate indexId="i" id="user" name="listForm" property="list" >
<bean:write name="user" property="name" />
.........
</logic:iterate
在userList.jsp中加入下面标签库可以自动显示多页,缺省一个页面显示30个条目。
<MultiPages:pager actionFormName="listForm" page="/userListAction.do">
<MultiPages:prev name="[Prev ]" />
<MultiPages:index displayCount="1" />
<MultiPages:next name="[Next ]" />
</MultiPages:pager>模型UserTest的批量查询功能已经全部完成。
以上是介绍基于开源Jdon框架开发软件系统中的CRUD和批量查询功能步骤,遵循模板化开发,开发人员使用起来轻松而不容易出错,适合软件生产和严格的项目管理。
附件:本案例代码结构图:
本案例全部代码(struts+jdon+jpa/hibernate架构):
业务模型类代码 |
@Entity private String userId; public String getName() { public void setUserId(String userId) { public void setName(String name) { |
持久层代码 |
public class JdbcDAO extends DaoTemplate { private final static Logger logger = Logger.getLogger(JdbcDAO.class); public JdbcDAO(CacheManager cacheManager, DaoCRUD daoCRUD) { public PageIterator getModels(int start, int count) throws Exception{ } |
业务层服务代码 基本是委托持久层操作的简单代码 |
public class TestServicePOJOImp implements TestService, Poolable{ private JdbcDAO jdbcDao; public TestServicePOJOImp(JdbcDAO jdbcDao) { public void createUser(EventModel em) { } public void updateUser(EventModel em) { } public void deleteUser(EventModel em) { } public UserTest getUser(String userId) { } public PageIterator getAllUsers(int start, int count) { } |
表现层代码 |
public class UserListAction extends ModelListAction { public Model findModelByKey(HttpServletRequest request, Object key) { } public PageIterator getPageIterator(HttpServletRequest request, int start, |
Jdon框架开发指南的更多相关文章
- SlickSafe.NET 开源权限框架开发指南
前言:本文适用于快速搭建权限系统的用户,尤其适用于希望有良好定义的权限模型建立:系统解决方案是在基于角色访问控制(RBAC)策略基础上的权限访问模型实现,主要完成了后台权限验证逻辑和前端权限数据验证的 ...
- Koa框架教程,Koa框架开发指南,Koa框架中文使用手册,Koa框架中文文档
我的博客:CODE大全:www.codedq.net:业余草:www.xttblog.com:爱分享:www.ndislwf.com或ifxvn.com. Koa -- 基于 Node.js 平台的下 ...
- ASP.NET Aries 开源开发框架:开发指南(一)
前言: 上周开源了Aries开发框架后,好多朋友都Download了源码,在运行过程里,有一些共性的问题会问到. 所以本篇打算写一下简单的开发指南,照顾一下不是太看的懂源码的同学,同时也会讲解一下框架 ...
- 开发指南专题二:JEECG微云高速开发平台JEECG框架初探
开发指南专题二:JEECG微云高速开发平台JEECG框架初探 2.JEECG框架初探 2.1演示系统 打开浏览器输入JEECG演示环境界址:http://demo.jeecg.org:8090/能够看 ...
- [Lua游戏AI开发指南] 笔记零 - 框架搭建
一.图书详情 <Lua游戏AI开发指南>,原作名: Learning Game AI Programming with Lua. 豆瓣:https://book.douban.com/su ...
- JVM 平台上的各种语言的开发指南
JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...
- iOS原生地图开发指南续——大头针与自定义标注
iOS原生地图开发指南续——大头针与自定义标注 出自:http://www.sxt.cn/info-6042-u-7372.html 在上一篇博客中http://my.oschina.net/u/23 ...
- nodejs开发指南读后感
nodejs开发指南读后感 阅读目录 使用nodejs创建http服务器; supervisor的使用及nodejs常见的调式代码命令了解; 了解Node核心模块; ejs模板引擎 Express 理 ...
- Libgdx 开发指南——目录
本系列文档选译自libgdx github项目 wiki : https://github.com/libgdx/libgdx/wiki 由于关于Libgdx的中文文档非常稀缺,因此在这里对官方Wik ...
随机推荐
- Android-异步图像装载机
在ListView加载图像是非常常见的场景,图像加载几个要求满足以下的: (1)是否画面位于网络或本地上,装载不应同步.但应该异步加载,例如,使用AsyncTask. (2)为了避免重复下载图片和网页 ...
- 实例学习SSIS(四)--使用日志记录和错误流重定向
原文:实例学习SSIS(四)--使用日志记录和错误流重定向 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习 ...
- js 计算过去和未来的时间距离现在多少天?
计算传入的任意一时间.计算出这个时间距离现在还有多少天!或者计算过去的时间距离现在已经过去了多少天! 返回值有两种! 1.负值 代表过去了多少天 2.正值 代表距离设定的时间还有多少天 说明:距离设定 ...
- sql 行转列 PIVOT 列转行 UNPIVOT
原文:sql 行转列 PIVOT 列转行 UNPIVOT 一: 现有表一(t_table1),想转为表二(t_table2)的格式. 表一: 年 公司 收入 2013 公司1 12 2013 公司2 ...
- 个推A/B测试评测
A/B测试在各类网站设计中已经是比较常见的,本文着重讲讲A/B测试在应用推送领域的作用. 目前国外开通A/B测试的推送服务商只有swrve,而国内的个推也在前不久发布的smart push 2.0中集 ...
- Oracle琐碎笔记2
备注:以下所有操作均在sqlplus中执行. 开始前输入:spool c:\jiyi.txt;结束后输入:spool off;就会记忆操作的所有记录save c:\sql.sql;保存sql脚本可以使 ...
- 【转】iOS 开发者必不可少的 75 个工具
原文地址:Ben 译文地址:伯乐在线 如果你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完成不同的任务. 软件开发同样如此.你可以从软件开发者如何使用工具中看出他水准如何.有经验的开发 ...
- .Net 异步随手记(一)
今天要记录的内容摘要是: 什么时候异步代码能“等”在那里,什么时候不会“等” 这两天Coding的时候碰到一个事儿,就是想让异步等在那里结果却直接执行过去了,比如这样: async static vo ...
- 圆形头像以及一些常见需求形状自定义ImageView组件
在实际开发中,我们经常会遇到这样的需求,就是无论图片长啥样,我们都要其显示成圆形.圆形加一个边框.矩形加边框,带圆角的矩形等等,lib和demo下载地址:https://github.com/mapl ...
- Unity3d物体模型(实现旋转缩放平移自动旋转)
基本功能实现:物体通过鼠标左键上下移动,中间键缩放.右键旋转,30秒没操作,物体自动旋转 实例代码: using UnityEngine; using System.Collections; publ ...