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")
public class TestServicePOJOImp implements TestService{
private JdbcDAO jdbcDao;
public TestServicePOJOImp(JdbcDAO jdbcDao) {
this.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"?>
<!DOCTYPE app PUBLIC "-//JDON//DTD Framework 2005 1.0 //EN" "http://www.jdon.com/jdonframework.dtd">
<app>
<services>
<pojoService name="testService" class="com.jdon.framework.test.service.TestServicePOJOImp"/>
</services>
</app>
|
这样,在servlet或jsp或struts的action等客户端代码中,我们可以使用如下代码调用TestServicePOJOImp,注意:以下代码没有具体TestServicePOJOImp类:
TestService testService = (TestService) WebAppUtil.getService("testService ", request);
testService.createUser(em);
|
以上步骤,只是简单展示框架的一个简要步骤,你可能没有觉得多了一个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"?>
<!DOCTYPE app PUBLIC "-//JDON//DTD Framework 2005 1.0 //EN" "http://www.jdon.com/jdonframework.dtd">
<app>
<services>
<pojoService name="testService" class="com.jdon.framework.test.service.TestServicePOJOImp"/>
<!-- 新增加的配置:jdbcDAO是被TestServiceImp调用的,是为其服务的。 -->
<component name="jdbcDAO" class="com.jdon.framework.test.dao.JdbcDAO"/>
</services>
</app>
|
再进一步,如果我们经常遇到一些类中需要一些常量或参数定义,那么可以使用如下配置:
<component name="jdbcDAO" class="com.jdon.framework.test.dao.JdbcDAO">
<constructor value="java:/TestDS"/>
</ component >?
|
这时,要求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-name> modelmapping-config </param-name>
<param-value> jdonframework.xml </param-value>
</context-param>
……
<listener>
<listener-class>com.jdon.container.startup.ServletContainerListener</listener-class>
</listener>
|
上述param-value可以配置多个配置,中间以逗号隔开,如下:
<context-param>
<param-name>modelmapping-config </param-name>
<param-value>com.jdon.framework.test.model.models.xml,
com.jdon.framework.test.service.services.xml,
com.jdon.framework.test.dao.dao.xml</param-value>?
</context-param>
|
第二:结合struts配置方式(需要struts基础知识):
在struts-config.xml中配置Plugin实现子类:
<plug-in className="com.jdon.strutsutil.InitPlugIn">
<set-property property="modelmapping-config" value="jdonframework.xml" />
</plug-in>
|
按这里查看更详细全面文档
增删改查(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
}
} |
如果想使用Doman Events模式,实现异步消息懒加载,如下步骤 :
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
public class UserTest extends Model {
private String userId;
private String name;
@Id
public String getUserId() {
return userId;
}
public String getName() {
return name;
}
public void setUserId(String userId) {
this.userId = userId;
}
public void setName(String name) {
this.name = name;
}
}
|
持久层代码 |
public class JdbcDAO extends DaoTemplate {
private final static Logger logger = Logger.getLogger(JdbcDAO.class);
public JdbcDAO(CacheManager cacheManager, DaoCRUD daoCRUD) {
super(cacheManager, daoCRUD);
}
public PageIterator getModels(int start, int count) throws Exception{
String GET_ALL_ITEMS_ALLCOUNT = "select count(1) from usertest ";
String GET_ALL_ITEMS = "select userId from usertest ";
return pageIteratorSolver.getDatas("", GET_ALL_ITEMS_ALLCOUNT, GET_ALL_ITEMS, start, count);
}
}
|
业务层服务代码
基本是委托持久层操作的简单代码 |
public class TestServicePOJOImp implements TestService, Poolable{
private final static Logger logger = Logger
.getLogger(TestServicePOJOImp.class);
private final static String USER_SAVE_ERROR = "USER.SAVE.ERROR";
private JdbcDAO jdbcDao;
public TestServicePOJOImp(JdbcDAO jdbcDao) {
this.jdbcDao = jdbcDao;
}
public void createUser(EventModel em) {
UserTest user = (UserTest) em.getModel();
try {
jdbcDao.insert(user);
} catch (Exception ex) {
logger.error(ex);
em.setErrors(USER_SAVE_ERROR);
}
}
public void updateUser(EventModel em) {
UserTest user = (UserTest) em.getModel();
try {
jdbcDao.update(user);
} catch (Exception ex) {
logger.error(ex);
em.setErrors(USER_SAVE_ERROR);
}
}
public void deleteUser(EventModel em) {
UserTest user = (UserTest) em.getModel();
try {
jdbcDao.delete(user);
} catch (Exception ex) {
logger.error(ex);
em.setErrors(USER_SAVE_ERROR);
}
}
public UserTest getUser(String userId) {
logger.debug(" get User from DAO + JDBC " + userId);
return (UserTest)jdbcDao.loadModelById(UserTest.class, userId);
}
public PageIterator getAllUsers(int start, int count) {
PageIterator pageIterator = null;
try {
pageIterator = jdbcDao.getModels(start, count);
} catch (Exception ex) {
logger.error(ex);
}
return pageIterator;
}
} |
表现层代码 |
public class UserListAction extends ModelListAction {
private final static Logger logger = Logger.getLogger(UserListAction.class);
public Model findModelByKey(HttpServletRequest request, Object key) {
Model model = null;
try {
logger.debug("get the model for primary key=" + key + " type:"+ key.getClass().getName());
TestService testService = (TestService) WebAppUtil.getService("testService", request);
model = testService.getUser((String)key);
} catch (Exception ex) {
logger.debug("get the model for primary key=" + key + " type:"+ key.getClass().getName());
logger.error(" error: " + ex);
}
return model;
}
public PageIterator getPageIterator(HttpServletRequest request, int start,
int count) {
PageIterator pageIterator = null;
try {
TestService testService = (TestService) WebAppUtil.getService("testService",
request);
pageIterator = testService.getAllUsers(start, count);
} catch (Exception ex) {
logger.error(ex);
}
return pageIterator;
}
}
|
更多Jdon框架专题讨论
JdonFramework作为一个免费开源软件开发平台,可以商用开发大多数数据库应用软件和管理软件: 电子商务软件 在线教育软件 税务软件 Web快速开发软件 财务软件 购物车软件 医院帐务软件 crm software medical software 人事薪资软件payroll software 在线购物软件 销售软件 项目管理软件 房产不动产管理软件 生产软件 PDM软件 制造业软件 仓库软件 采购软件 进销存软件 危险源监控软件 物流软件 超市软件 银行软件 保险软件 汽车软件 医疗软件 电子软件 自动化软件 服装软件 烟草软件 分销管理软件 供应商管理软件
|