Cosmos开发指南(二)

    上一篇博文主要介绍了Cosmos框架使用HSQLDB作为后台数据库,并且仅执行一条简单的SQL时的开发流程,本篇博文将改换为MySQL数据库,介绍Cosmos如何配置数据源,以及在Cosmos框架下如何进行复杂的业务逻辑的开发。

     这一次,我们将不再使用Cosmos-Example程序,改为使用Cosmos-Template程序,Cosmos-Template程序是Cosmos开发团队给出的一个配置好Cosmos框架的空白应用程序,开发者仅需要在这个程序的基础上做一定得修改,即可开发自己的业务逻辑。

     到Cosmos项目的下载页面,URL是http://code.google.com/p/cosmos4j/downloads/list,下载Cosmos-Template的最新版,撰写本文时,最新版为1.0.2。如下图所示。

Cosmos开发指南(二)_第1张图片

     下载下来的应该是一个zip文件,将这个文件解压缩,在项目目录下有CosmosTemplate/application目录,简单的部署方式是将application复制到Tomcat下的webapps目录,也可以通过配置Context,直接指向刚刚解压缩的目录,下面就采用后一种方式进行配置。

     停止Tomcat,复制CosmosTemplate/etc/tomcat/Catalina/cosmos.com/ROOT.xml文件到Tomcat安装目录下的conf/Catalina/localhost/目录,将文件名修改为cosmos.xml,修改其中的几个属性:

     将path=""改为path="/cosmos",将docBase="E:/Projects/Java/CosmosTemplate/application"改为刚刚解压缩的目录下面的application目录,比如:docBase="E:/CosmosTemplate/application",最后,修改数据源的配置参数。这里先不要启动Tomcat,下一步先将Cosmos需要的数据库相关表导入到数据源中。

     到解压缩的目录下找到”CosmosTemplate/database/mysql/”目录,在这里有最新的数据库备份文件,本文导入的是” cosmos 20081208 1128.sql”,导数据库的工具建议选择MySQL Administrator。导入表之后的数据库如下所示:

Cosmos开发指南(二)_第2张图片

     从界面上看有相当多的表,其实与Cosmos核心框架有关的仅为三张表,也就是表名为tb_cos_开头的表。其余表名开头为tb_sys_的表与Cosmos-SSO统一身份认证有关,而tb_com_开头的表则是一些通用表。

     到解压缩之后的目录中,找到CosmosTemplate/application/WEB-INF/web.xml文件,检查数据源的配置是否与cosmos.xml中的数据源一致。web.xml中的配置如下所示:

 

 1 < resource-ref >  
 2
 3 < res-ref-name > jdbc/project res-ref-name >  
 4
 5 < res-type > javax.sql.DataSource res-type >  
 6
 7 < res-auth > Container res-auth >  
 8
 9 resource-ref >  
10
11

 

cosmos.xml中的配置如下所示:

 

ContractedBlock.gif ExpandedBlockStart.gif Resource
1<Resource name="jdbc/project" auth="Container" 
2
3type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" 
4
5url="jdbc:mysql://localhost:3306/cosmos?useUnicode=true&characterEncoding=utf8" username="cosmos" password="cosmos" 
6
7maxActive="20" maxIdle="10" maxWait="-1" />
8

 

     下面开始配置Cosmos框架,到目录CosmosTemplate/application/WEB-INF/home/etc/core/下,找到core-config.xml,打开这个xml文件,并找到最后一部分的domain的配置,如下所示:

 

ContractedBlock.gif ExpandedBlockStart.gif Domain
 1<domain name="jndi" category="db" 
 2
 3class="com.microbrain.cosmos.core.domain.db.mysql.CosmosMysqlJndiDomain" 
 4
 5type="master" cachable="false" reloadable="false" debug="INFO"> 
 6
 7<init-param name="binding" value="jdbc/project" /> 
 8
 9<init-param name="schema" value="cosmos" /> 
10
11<init-param name="default-call-executer" value="callExecuter" /> 
12
13<init-param name="command-manager" 
14
15value="com.microbrain.cosmos.dev.StandardCosmosCommandManager" /> 
16
17<commands> 
18
19<command name="login" executer="sqlExecuter" debug="INFO" 
20
21type="standard"> 
22
23<argument name="name" in-out-type="IN" converter="string" /> 
24
25<argument name="service" converter="string" /> 
26
27[CDATA[SELECT ID, PASSWORD FROM tb_sys_user WHERE NAME = ? AND TYPE = ?]]> 
28
29command> 
30
31<command name="needed" executer="sqlExecuter" debug="INFO" 
32
33type="standard"> 
34
35<argument name="object" in-out-type="IN" converter="string" /> 
36
37<argument name="operation" converter="string" /> 
38
39[CDATA[SELECT permission.PERMISSION_CODE FROM tb_sys_permission AS permission WHERE permission.OBJECT=? AND permission.OPERATION=?]]> 
40
41command> 
42
43<command name="owned" executer="sqlExecuter" debug="INFO" 
44
45type="standard"> 
46
47<argument name="passportId" in-out-type="IN" converter="string" /> 
48
49<argument name="passportId" converter="string" /> 
50
51[CDATA[SELECT permission.OBJECT, permission.OPERATION, permission.PERMISSION_CODE FROM tb_sys_permission AS permission 
52
53LEFT JOIN tb_sys_user_permission AS up ON up.PERMISSION_ID=permission.ID 
54
55LEFT JOIN tb_sys_role_permission AS rp ON rp.PERMISSION_ID=permission.ID 
56
57LEFT JOIN tb_sys_user_role AS ur ON ur.ROLE_ID=rp.ROLE_ID 
58
59WHERE up.USER_ID=? OR ur.USER_ID=?]]> 
60
61command> 
62
63commands> 
64
65domain>
66

 

     其中domain标签的属性包括:

     name:为这个domain所起的一个名称,将来在链接中调用时使用;

     category:表示哪些executor可以被这个域使用,executor的配置就在domain配置的上面;

     class:这个域的实现类;

     type:域的类型,仅有两类,分别是master和slave,master表示这个域可以用来存储命令,也就是在这个数据库中有上面导入的核心的三张表,如果是slave域,则表示本域没有存储命令,一个项目中,应该有且仅有一个master域,可有零到多个slave域;

     cachable:表示Cosmos框架是否缓存本域的命令,如果启用了缓存,并且后面的reloadable配置为false的话,则开发出的新命令将需要重启Tomcat才能访问,建议在运行环境中启用cachable;

     reloadable:表示每次调用命令时,是否重新从系统存储中装载所有命令,这个配置仅在cachable为true时有效;

     debug:配置本域的调试级别。

     上述配置属性均不需要修改,在domain的标签下还有几个初始化参数,分别是:

     binding:表示本域绑定的数据源的jndi名;

     schema:表示本域访问的数据库名;

     default-call-executer:表示本域使用的默认存储过程的executor;

     command-manager:表示如果本域为master域,则用来管理命令的管理类是什么。

     因此,需要将binding和schema修改为对应的正确值。

     经过上面的配置,CosmosTemplate就全部配置好了,启动Tomcat,并且访问如下页面,http://localhost:8080/cosmos/index.jsp,如果看到了和上一篇博文一样的首页界面,则表示配置成功了,如果出现以下异常:

 

ContractedBlock.gif ExpandedBlockStart.gif Exception
 1org.apache.jasper.JasperException: /index.jsp(15,89) Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlCoreTLV 
 2
 3org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40
 4
 5org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407
 6
 7org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:88
 8
 9org.apache.jasper.compiler.Parser.processIncludeDirective(Parser.java:343
10
11org.apache.jasper.compiler.Parser.parseIncludeDirective(Parser.java:376
12
13org.apache.jasper.compiler.Parser.parseDirective(Parser.java:484
14
15org.apache.jasper.compiler.Parser.parseElements(Parser.java:1439
16
17org.apache.jasper.compiler.Parser.parse(Parser.java:137
18
19org.apache.jasper.compiler.ParserController.doParse(ParserController.java:255
20
21org.apache.jasper.compiler.ParserController.parse(ParserController.java:103
22
23org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:170
24
25org.apache.jasper.compiler.Compiler.compile(Compiler.java:332
26
27org.apache.jasper.compiler.Compiler.compile(Compiler.java:312
28
29org.apache.jasper.compiler.Compiler.compile(Compiler.java:299
30
31org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:586
32
33org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317
34
35org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342
36
37org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267
38
39javax.servlet.http.HttpServlet.service(HttpServlet.java:717
40
41com.microbrain.cosmos.web.filters.EncodingFilter.doFilter(EncodingFilter.java:64
42
43

 

     则表示系统中没有安装jstl的库,去JSTL的网站下载jstl.jar和standard.jar文件,放到CosmosTemplate/application/WEB-INF/lib目录下,或者从CosmosExample下面的WEB-INF/lib中也可以找到这两个文件。正常启动的主界面应该如下图所示:

Cosmos开发指南(二)_第3张图片

     下面就开始基于配置好的环境进行开发,由于笔者经常使用的MySQL存储过程的开发环境为SQLYog,因此,本文将基于SQLYog进行说明。读者可以使用习惯的MySQL管理工具来开发。后续部分将介绍针对一个简单的表进行的查询操作,涉及到界面参数如何与存储过程参数对应,如何显示执行结果。

     建立一张Student表,字段包括ID[CHAR(32)],NAME[VARCHAR(255)],REAL_NAME[VARCHAR(512)],GENDER[TINYINT(1)]等,在表中插入一部分测试数据。

     下面建立一个存储过程,名称为searchStudents,参数为studentName,表示将通过用户输入的学生名称进行学生查询,存储过程的代码如下所示:

 

ContractedBlock.gif ExpandedBlockStart.gif SearchStudents
 1DELIMITER $$ 
 2
 3USE `cosmos`$$ 
 4
 5DROP PROCEDURE IF EXISTS `searchStudents`$$ 
 6
 7CREATE DEFINER=`cosmos`@`%PROCEDURE `searchStudents`(IN studentName VARCHAR(512)) 
 8
 9BEGIN 
10
11SET @namePattern = CONCAT('%', studentName, '%'); 
12
13SELECT * FROM student WHERE NAME LIKE @namePattern OR REAL_NAME LIKE @namePattern
14
15END$$ 
16
17DELIMITER ; 
18

 

     下面到CosmosTemplate的首页上,去查看这个命令是否已经创建成功了,在左侧菜单中找到“系统域本地命令”,单击下面的jndi域,右侧中会列出这个域的所有存储过程,如果存储过程创建成功了,在这个列表里应该就会有刚刚创建的searchStudents命令,如下图所示:

Cosmos开发指南(二)_第4张图片

     下面为这个命令建立相应的页面,同样地,我们在CosmosTemplate/application/test的目录下放置我们创建的jsp,建立students.jsp文件,并键入以下的代码:

 

ContractedBlock.gif ExpandedBlockStart.gif students.jsp
 1ExpandedBlockStart.gifContractedBlock.gif<%@ page pageEncoding="UTF-8" language="java" contentType="text/html;charset=UTF-8"%><%@ include file="/include.inc.jsp"%>DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 2
 3<html xmlns="http://www.w3.org/1999/xhtml"> 
 4
 5<head> 
 6
 7<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
 8
 9<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> 
10
11<link href="styles/default/css/main.css" rel="stylesheet" type="text/css" /> 
12
13<script type="text/javascript" src="styles/default/scripts/main.js">script> 
14
15head> 
16
17<body onresize="fixSubHeight();" onload="fixSubHeight();"> 
18
19<iframe id="hiddenFrame" name="hiddenFrame" style="display:none;">iframe> 
20
21<div id="listContent"> 
22
23<h1><span>学生列表span>h1> 
24
25<div id="top" class="toolBar"> 
26
27<div class="left" style="width:100%;"> 
28
29<form name="searchForm" id="searchForm" method="post" enctype="application/x-www-form-urlencoded" style="border:none;"> 
30
31<input type="text" name="studentName" value="${param.studentName}" /> 
32
33<button onclick="searchForm.submit();">查询button> 
34
35form> 
36
37div> 
38
39div> 
40
41<div id="tab" align="center"> 
42
43<table class="defaultList"> 
44
45<tr> 
46
47<th scope="col">学生名称th> 
48
49<th scope="col">学生真实姓名th> 
50
51<th scope="col">学生性别th> 
52
53tr><c:forEach items="${present:commandFirstList('jndi', 'searchStudents', result)}" var="student"> 
54
55<tr onclick="selectRow(this);"> 
56
57<td>${student.name}td> 
58
59<td>${student.realName}td> 
60
61<td>${student.gender ? "女" : "男"}td> 
62
63tr>c:forEach> 
64
65table> 
66
67div> 
68
69<div id="bottom" class="toolBar"> 
70
71<div class="left"> 
72
73div> 
74
75<div class="right"> 
76
77div> 
78
79div> 
80
81div> 
82
83body> 
84
85html> 
86

 

     在这些代码里,c:forEach标签库使用的是JSTL的标准标签库,present:commandFirstList是Cosmos框架提供的EL函数,用来获取一个命令的第一个结果列表,三个参数分别是domain的名字,命令名字,以及从request中获得的命令执行结果result参数。其中最后的result参数是固定的,代表命令的执行结果。在这个页面中,还有一个查询的表单,表单里的文本框是查询的关键字,需要将这个文本框的名字和后台存储过程的名字对应起来,也就是将其命名为studentName即可,框架会自动根据存储过程的参数列表将这个表单里的所有值进行匹配对应,并进行相应的参数类型转换,最后将这些参数传递给存储过程执行。上述页面的执行可通过下面链接进行:

     http://localhost:8080/cosmos/cosmos.slet?domain=jndi&method=searchStudents&forward=test.students

     在Cosmos框架中进行一次页面访问的链接结构是调用的核心Servlet是在web.xml中配置的映射路径,在这里是cosmos.slet,参数中必须包含的包括domain参数,也就是在core-config.xml中配置的domain名称,method参数是刚才开发的searchStudents,forward参数表示要跳转的页面,在这里将页面路径进行了一些处理,比如将路径中的/替换成.,将后缀jsp去掉等。因此,如果读者将students.jsp放置到根目录的话,则forward=students即可。本样例程序的执行结果如下:

Cosmos开发指南(二)_第5张图片

    在这个界面中,用户可以通过上面的搜索框进行学生搜索,输入学生部分的英文名称或者中文名称进行检索。如下图所示,是输入Zhang的查询结果:

Cosmos开发指南(二)_第6张图片

    好了,经过上面的步骤,就完成了一个简单的查询表单和查询结果的功能制作,可以看出,在开发过程中间,如果对存储过程或者JSP页面有任何调整,都不会导致重新启动Tomcat,并且代码量相对要少很多,从而相对地提高了开发速度和开发难度。

    附件中是本例子相关的Student表和表中的数据,searchStudents存储过程,以及对应的students.jsp页面的源代码,读者可以简单地将这些东西导入到项目中,来测试上面的开发过程。

    注意:本例中的所有导入导出的数据库SQL文件都是用MySQL Administrator完成的,因此,建议读者在使用时,尽量使用MySQL Administrator进行操作,避免发生错误。

    本样例所涉及到的程序压缩包:

    student.zip

转载于:https://www.cnblogs.com/microsaas/archive/2009/10/31/cosmos_development_2.html

你可能感兴趣的:(Cosmos开发指南(二))