上一级 首页 下一级
开发一个简单Jdon应用系统
以下以一个简单需求说明Struts+Jdon+JDBC的开发,源码见Jdon框架源码包中的SimpleJdonFrameworkTest/JdonFrameworkTest项目,更复杂一些的案例可见源码包中的另外一个JdonNews,简单需求如下:
实现User模型的数据新增、修改、删除和批量查询。
User模型有两个字段userId和name。
在JBuilder配置JdonFramework为IDE驱动包
如果你使用JBuilder开发工具,按下列步骤:
将JdonFramework导入项目库,或者成为整个配置库。如图:

同时,配置Framework配置,如下图:

该配置是为了激活项目Web开发支持JdonFramework的标签库taglib,使用JdonFramework开发应用系统时,自动支持多页批量查询和树形结构显示,这两种功能需要在Jsp页面导入特定的标签库,该设置就是为实现此功能。
注意:由于JBuilder的部分BUG,最好将JdonFramework.jar的MEAT-INF/tlds目录下的MultiPages.tld等文件解压出,形成单独文件,在这里导入这些单独文件。
配置WEB模块时,需选中Web框架,如下图:

如果你使用的是Eclipse,在将JdomFramework.jar作为一般的JAR导入项目。
另外,如果你的JBuilder中看不到源码包下面的jdonframework.xml文件,例如本项目的配置文件在com.jdon.framework.test包下面,但是你展开后,可能只发现application.properties等资源文件,但是没有发现jdonframework.xml,解决方式:
项目属性中,Build节点的子节点Resource,在下拉菜单中选择XML,然后点选右上部的copy即可(原来为do not copy)。
建模
开始开发程序, 建立Model实现UserTest
建立Model对应的ModelForm:UserActionForm是继承ModelForm,而ModelForm实际也是继承Struts的ActionForm。
将UserTest中方法和字段拷贝到UserActionForm,原则上这两者内容是一致的,JdonFramework将自动在这两个对象之间拷贝相同方法的值,但是它们服务的对象不一样,UserTest是为了中间层或后台业务层服务的;而UserActionForm是为了界面服务的,两者分离是为了使得我们的业务层和界面分离,这样,当有新的可替代Struts界面框架出现,我们可以不修改业务层代码下更换界面框架。
业务层开发
Jdon框架支持Web应用和EJB应用,下面两种方案中任意选一种,也就是说,是采取POJO服务实现或EJB服务实现取决你的系统架构,如果你不想使用EJB,那么就采取POJO服务,相关EJB服务实现及其他就都不要看了。
POJO服务实现
POJO服务只要编写一个TestService接口和一个实现TestServicePOJOImp即可,在实现子类中调用持久层jdbcDao.
EJB服务实现
这里使用EJB实现业务层功能,建立一个无态Session Beans
为TestEJB,主要负责UserTest的数据库增删改查等功能,这部分开发不在JdonFramework规定之类,而要遵循EJB相关规定。这部分开发细节可参见有关JBuilder开发EJB教程。
建立一个实体Bean名为User:首先需要将JBuilder配置成能够直接访问数据库,我们使用MySQL数据库,配置后,重新启动JBuilder。
配置JBoss中的数据源,数据源JNDI名称是DefaultDS。在代码中调用JBoss的JNDI,JBoss有特定规定,应该是java:/DefaultDS。
创建CMP时有两种方式:一种直接创建新的CMP,当该J2EE部署时,将自动创建CMP对应的数据表,或者先创建数据表,由数据表导入CMP。本演示采取后者方式。
完成Session Bean TestEJB的新增、修改和删除方法,下面完成查询和批量查询方法,查询方法建议使用DAO+JDBC实现。
持久层:增删改查CRUD实现
持久层的增删改查功能可使用Jdon框架的Jdbc模板实现:
新增操作
public void insert(UserTest userTest) throws Exception{
String sql = "INSERT INTO testuser (userId , name) "+
"VALUES (?, ?)";
List queryParams = new ArrayList();
queryParams.add(userTest.getUserId());
queryParams.add(userTest.getName());
jdbcTemp.operate(queryParams,sql);
clearCacheOfItem();
}
修改操作:
public void update(UserTest userTest) throws Exception{
String sql = "update testuser set name=? where userId=?";
List queryParams = new ArrayList();
queryParams.add(userTest.getName());
queryParams.add(userTest.getUserId());
jdbcTemp.operate(queryParams,sql);
clearCacheOfItem();
}
删除操作:
public void delete(UserTest userTest) throws Exception{
String sql = "delete from testuser where userId=?";
List queryParams = new ArrayList();
queryParams.add(userTest.getUserId());
jdbcTemp.operate(queryParams,sql);
clearCacheOfItem();
}
查询操作:
public UserTest getUser(String Id) {
String GET_FIELD = "select * from testuser where userId = ?";
List queryParams = new ArrayList();
queryParams.add(Id);
UserTest ret = null;
try {
List list = pageIteratorSolverOfUser.queryMultiObject(queryParams,
GET_FIELD);
Iterator iter = list.iterator();
if (iter.hasNext()) {
Map map = (Map) iter.next();
ret = new UserTest();
ret.setName((String) map.get("name"));
ret.setUserId((String) map.get("userId"));
}
} catch (Exception se) {
}
return ret;
}
持久层:批量查询实现
这里是为了实现批量查询,如果不需要批量查询,可跳过此步:
持久层需要向前台提供数据库等持久层数据的查询和获得,一般可通过Jdon框架的简单JDBC模板实现,我们创建一个JdbcDao类。
PageIterator对象创建
首先为每个Model引入分页对象;
//通过JNDI获得Datasource
dataSource = (DataSource) sl.getDataSource(JNDINames.DATASOURCE);
//框架使用 为每个Model建立一个分页对象。
pageIteratorSolverOfUser = new PageIteratorSolver(dataSource);
三个方法实现
JdbcDao有三个缺省方法必须才能完成从数据库中获得所要求的数据,这三个方法分别是:
User getUsers(String Id); //查询获得单个Model实例
PageIterator getUsers(int start, int count); //查询某页面的所有Model的ID集合
public void clearCacheOfUser() ; //清除某个Model的缓存。
上述三个方法中,只有一个方法需要编写代码,其它可委托JdonFramework提供的工具API方法完成。
第一个方法完成: 编写获得单个Usertest的数据库查询方法:从现成的示例拷贝如下:
public UserTest getUser(String Id) {
String GET_FIELD = "select * from testuser where userId = ?";
List queryParams = new ArrayList();
queryParams.add(Id);
UserTest ret = null;
try {
List list = pageIteratorSolverOfUser.queryMultiObject(queryParams,
GET_FIELD);
Iterator iter = list.iterator();
if (iter.hasNext()) {
Map map = (Map) iter.next();
ret = new UserTest();
ret.setName((String) map.get("name"));
ret.setUserId((String) map.get("userId"));
}
} catch (Exception se) {
}
return ret;
}
第二个方法实现:编写分页查询SQL实现方法,直接使用框架内部的方法如下:
String GET_ALL_ITEMS_ALLCOUNT = "select count(1) from testuser ";
String GET_ALL_ITEMS = "select userId from testuser ";
return pageIteratorSolverOfUser.getDatas("", GET_ALL_ITEMS_ALLCOUNT,
GET_ALL_ITEMS, start, count);
注意getDatas的方法参数使用,参考批量查询章节
第三个方法实现.:编写缓存清除方法:该方法是在该Model被新增或删除等情况下调用。 这样,当前台页面新增新的数据后,批量查询能够立即显示新的数据,否则将是缓存中老的数据集合,无法立即更新。
public void clearCacheOfUser() {
pageIteratorSolverOfUser.clearCache();
}
JdbcDAO模板化编程到此结束。
下一步,使用EJB的Session Bean包装这个JdbcDao,如果服务层不是使用EJB实现,直接通过一般的POJO服务包装JdbcDao。
JdonFramework.xml配置
根据http://www.jdon.com/ jdonframework.dtd导出XML:
增删改查CRUD配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE app PUBLIC "-//JDON//DTD Framework 2005 1.0 //EN" "http://www.jdon.com/jdonframework.dtd">
<app>
<models>
<model key="userId" class ="com.jdon.framework.test.model.UserTest">
<actionForm name="userActionForm"/>
<handler>
<service ref="testService">
<getMethod name="getUser" />
<createMethod name="createUser" />
<updateMethod name="updateUser" />
<deleteMethod name="deleteUser" />
</service>
</handler>
</model>
</models>
….. <!-- 服 务 配置 -->
</app>
注意Handler配置有两种:缺省是上述配置,如果情景复杂,需要代码完成,则编写一个Hamdler类继承ModelHandler实现即可,然后在上述handler段配置如下:
<handler class=”xxxx.yourHandler” />
POJO服务配置实现
<services>
<pojoService name="testService" class="com.jdon.framework.test.service.TestServicePOJOImp"/>
<pojoService class="com.jdon.framework.test.dao.JdbcDAO" name="jdbcDAO">
<constructor value="java:/DefaultDS"/>
</pojoService>
</services>
上面定义了一个POJO服务:com.jdon.framework.test.service.TestServicePOJOImp,因为TestServicePOJOImp中使用了JdbcDAO,这里配置了com.jdon.framework.test.dao.JdbcDAO实现,如果你使用其他持久层技术,可以在此更换另外一个JdbcDao。
这里的jdbcDAO需要数据库连接,数据库连接参数不是在应用程序中配置,而是使用J2EE服务器已经配置成功的JNDI名称,Tomcat中配置JNDI数据库连接池可见:http://www.7880.com/Info/Article-37f05fa0.html;JBoss的JND配置见本站相关文章。
特别注意:
java:/DefaultDS是JBoss的数据库连接池JNDI写法,如果你使用其他服务器,参考他们的JNDI要求写法。
例如 在JBoss的mysql-ds.xml中配置一个数据库的JNDI为TestDS。
那么在J2EE系统中(上面JdbcDAO配置中),就应该前面加一个java:/ 就成了java:/TestDS。
如果Tomcat的server.xml配置数据库的JNDI成TestDS
那么在J2EE中(上面JdbcDAO配置中),使用该JNDI的名称应为: java:comp/env/TestDS。
两者写法不一样,不同的服务器写法都有规定。也可以在web.xml配置JNDI引用。
如果服务配置中存在ejbService,如下:
<ejbService name="testService2" >
<jndi name="TestEJB" />
<ejbLocalObject class="com.jdon.framework.test.ejb.TestEJBLocal"/>
<interface class="com.jdon.framework.test.service.TestService" />
</ejbService>
那么可以在ejbService和pojoService之间更换,将pojoService和ejbService的name值对换一下即可, 将<ejbService name="testService2" >更换为<ejbService name="testService" >,将<pojoService name="testService"改名为 <pojoService name="testService2", 这样,Model部分配置的服务指向就从调用POJO服务更换到调用EJB服务了。
表现层:增删改查CRUD配置
CRUD功能无需编制代码,代码功能已经在上节的jdonframework.xml中配置完成,这里只要配置struts的页面流程struts-config.xml配置和编写Jsp两步即可。
(1) 按照前面章节规则二:配置ModelViewAction介绍的。实现新增或编辑视图输出的Action:
<action name="userActionForm" path="/userAction" type="com.jdon.strutsutil.ModelViewAction">
<forward name="create" path="/user.jsp" />
<forward name="edit" path="/user.jsp" />
</action>
上述配置中,需要修改的跟Model名称相关的配置。
(2)创建user.jsp页面。
在user.jsp中要增加一行关键语句:
<html:hidden property="action"/> 用来标识新增 修改等动作。
(3) 配置userSaveAction实现数据真正操作。
<action name="userActionForm" path="/userSaveAction"
type="com.jdon.strutsutil.ModelSaveAction">
<forward name="success" path="/result.jsp" />
<forward name="failure" path="/result.jsp" />
</action>
(4) 创建数据操作结果页面result.jsp, 上述配置修改不大,需要修改的跟Model名称相关的配置。
表现层:批量查询实现
CRUD功能只需配置和Jsp实现就可以,而批量查询表现层需要进简单编码,然后再需要配置和Jsp完成。还有一个区别是:前者无需编码,替代的是需要配置jdonframework.xml;而后者因为编码实现;无需配置jdonframework.xml了。
编码:UserListAction
UserListAction继承ModelListAction实现,按照前面批量查询章节,这里完成两个方法:getPageIterator和findModelByKey:
getPageIterator方法如下:
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;
}
findModelByKey方法:
public Model findModelByKey(HttpServletRequest request, Object key) {
Model model = null;
try {
TestService testService = (TestService) WebAppUtil.getService("testService", request);
model = testService.getUser( (String) key);
} catch (Exception ex) {
logger.error(ex);
}
return model;
}
代码中:
TestService testService = (TestService) WebAppUtil.getService("testService", request);
其中testService是jdonframework.xml配置中<pojoService name=" testService "> 中名称。
Struts-config.xml配置
(1)配置一个批量查询的ActionForm: 首先在struts-config.xml创建一个用于批量分页查询的ActionForm,固定推荐名称为listForm。
<form-bean name="listForm" type="com.jdon.strutsutil.ModelListForm" />
(2)配置UserListAction,按照普通Struts 的action配置
<action name="listForm" path="/userListAction" type="jdonframeworktest.web.UserListAction" >
<forward name="success" path="/userList.jsp" />
</action>
(4)编写userList.jsp,用于分页显示查询结果。
在userList.jsp中使用到分页的标签库:
<%@ taglib uri="/WEB-INF/MultiPages.tld" prefix="MultiPages" %>
<MultiPages:pager actionFormName=" Struts-config.xml中formBeans名称:listForm" page="Struts-config.xml中当前的action path值:/userListAction.do">
<MultiPages:prev>前页</MultiPages:prev>
<MultiPages:index />
<MultiPages:next>后页</MultiPages:next>
</MultiPages:pager>
我们将userList.jsp作为本演示首页,将新增 修改和删除等操作的执行集中在这个页面实现,使用JavaScript来实现。
基本全部完成。
配置启动Jdon框架
(1)配置jdonframework.xml在struts-config.xml中。
<plug-in className="com.jdon.strutsutil.InitPlugIn">
<set-property property="modelmapping-config" value="jdonframework.xml完整路径" />
</plug-in>
(2)将jdonframework.xml打包到你的Web项目。
否则,后台控制台会出现:
[InitPlugIn] looking up a config: jdonframework.xml
[InitPlugIn] cannot locate the config:: jdonframework.xml
打包部署
有两种方式打包成部署文件.war或.ear。
第一:如果是Eclipse工具,使用Ant进行打包,在本系统源码中已经编制好build.xml文件,更改其中J2EE服务器为的路径后,即可直接运行Ant打包。
第二:通过JBuilder直接打包,点本项目的Web项目,选择make即可,将自动出现xxx.war部署包(如果你是Tomcat就不会出现war文件,只能安装Tomcat方式配置)。
注意,将Web项目中去除任何包,也就是说WEB-INF/lib下没有任何包,Struts和JdonFramework包都放置在JBoss的server/default/lib下。
如果出现与tld相关的错误, 如:
File "/WEB-INF/MultiPages.tld" not found
解决:在web.xml中应该有下面两行tld配置:
<taglib>
<taglib-uri>/WEB-INF/MultiPages.tld</taglib-uri>
<taglib-location>/WEB-INF/MultiPages.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/TreeView.tld</taglib-uri>
<taglib-location>/WEB-INF/TreeView.tld</taglib-location>
</taglib>
并且确保/WEB-INF/MultiPages.tld和/WEB-INF/TreeView.tld下文件存在,这两个MultiPages.tld和TreeView.tl在JdonFramework.jar中的META-INF/tlds中,可手工拷贝过去。
使用JBuilder2005直接打包时,缺省是不会将所有的编译好class打包进去的,同时也不会将jdonframework.xml等资源文件打包进去,我们需要经过特别步骤处理:
选择项目的Web模块如testweb,右键点选属性,选择其中的Content,点选include all classes and resources,在Content子节点中,选择Dependencies,将所有包都exclude all,因为这些包我们事先已经放置在JBoss的server/default/lib下,不需要在本Web模块中携带。
确定后,重新编译一次项目,检查Web模块如testweb下的testweb.war文件,展开后,检查是否有jdonframework.xml,如果没有,接着如下步骤:
再次选择项目的Web模块如testweb,右键点选属性,选择Content,这次选择include speified filtered file and resource, 然后点按Add Filters,输入**/*.*,表示全部资源,确定。
再到Add Filters下面选择Add File,将jdonframework.xml等资源文件加入。
再次编译整个项目,检查war文件,应该所有class和资源文件都包括其中了。
更多详细错误,打开JBoss日志文件:server/default/log/server.log,找到server.log中第一个ERROR信息,分析原因,或者贴到Jdon框架开发论坛中。
运行案例
打开浏览器,键入http://localhost:8080/testWeb/index.jsp
我们将index.jsp导向真正执行/userListAction.do
网上实时演示网址: http://www.jdon.com/testWeb/
当在JBoss或Tomcat控制台 或者日志文件中出现下面字样标识Jdon框架安装启动成功:
<======== Jdon Framework started successfully! =========>
本章节源码在Jdon框架源码包的samples中SimpleJdonFrameworkTest/JdonFrameworkTest
上一级 首页 下一级
更多Jdon框架专题讨论
JdonFramework作为一个免费开源软件开发平台,可以商用开发大多数数据库应用软件和管理软件: 电子商务软件 在线教育软件 税务软件 Web快速开发软件 财务软件 购物车软件 医院帐务软件 crm software medical software 人事薪资软件payroll software 在线购物软件 销售软件 项目管理软件 房产不动产管理软件 生产软件 PDM软件 制造业软件 仓库软件 采购软件 进销存软件 危险源监控软件 物流软件 超市软件 银行软件 保险软件 汽车软件 医疗软件 电子软件 自动化软件 服装软件 烟草软件 分销管理软件 供应商管理软件
|