随笔-23  评论-6  文章-1  trackbacks-0
  2005年9月15日

sourceforge http://www.sourceforge.net
java.net http://www.java.net

www.eclipse.org

www.opensource.org

Lomboz http://www.objectlearn.com/index.jsp (J2EE plugin for Eclipse)
htmlArea http://sourceforge.net/projects/itools-htmlarea/ (所见即所得的在线HTML编辑器)
XmlBuddy http://www.xmlbuddy.com/ (XML Editor plugin for Eclipse)
JFreeChart http://www.jfree.org/ (用于生成图表的项目)
EclipseME http://eclipseme.sourceforge.net/ (J2ME Developmnt Plugin for Eclipse)
mvnForum http://sourceforge.net/projects/mvnforum/ (论坛)
jChatBox http://www.javazoom.net/index.shtml (用servlet实现的WEB聊天引擎)
POI http://jakarta.apache.org/poi/index.html (用于处理Excel,WORD等文档的项目)
FileUpload http://jakarta.apache.org/commons/fileupload/ (用于处理HTTP文件上传得项目)
PDFBox http://sourceforge.net/projects/pdfbox/ (处理PDF文档的项目)
Lucene http://jakarta.apache.org/lucene/index.html (搜索引擎)
Digester http://jakarta.apache.org/commons/digester/ (处理XML信息的项目)
DBCP http://jakarta.apache.org/commons/dbcp/ (数据库连接池)
AXIS http://ws.apache.org/axis/ (WebService 的实现框架)
Jetspeed http://portals.apache.org/jetspeed-1/ (Portal)
HSQLDB http://sourceforge.net/projects/hsqldb/ (Im memory Database Engine)
CEWOLF http://sourceforge.net/projects/cewolf/ (一套标签库实现Web报表,使用的是jFreeChart引擎)
Struts Menu http://sourceforge.net/projects/struts-menu/ (基于Struts的Web菜单项目)
htmlparser http://sourceforge.net/projects/htmlparser/ (用于解析HTML信息的项目)
Mondrian http://sourceforge.net/projects/mondrian/(Open Source OLAP Database)
ProGuard http://sourceforge.net/projects/proguard/(Java的混淆器)
InfoGlue http://sourceforge.net/projects/infoglue/ (J2EE 内容管理系统)
JPivot http://sourceforge.net/projects/jpivot/ (基于WEB的OLAP 展现)
http://java-source.net/

http://www.javaalmanac.com - Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧的用法及示例代码, 这是一个不错的去处.
http://www.onjava.com - O'Reilly的Java网站. 每周都有新文章.
http://java.sun.com - 官方的Java开发者网站 - 每周都有新文章发表.
http://www.developer.com/java - 由Gamelan.com 维护的Java技术文章网站.
http://www.java.net - Sun公司维护的一个Java社区网站.
http://www.builder.com - Cnet的Builder.com网站 - 所有的技术文章, 以Java为主.
http://www.ibm.com/developerworks/java - IBM的Developerworks技术网站; 这是其中的Java技术主页.
http://www.javaworld.com - 最早的一个Java站点. 每周更新Java技术文章.
http://www.devx.com/java - DevX维护的一个Java技术文章网站.
http://www.fawcette.com/javapro - JavaPro在线杂志网站.
http://www.sys-con.com/java - Java Developers Journal的在线杂志网站.
http://www.javadesktop.org - 位于Java.net的一个Java桌面技术社区网站.
http://www.theserverside.com - 这是一个讨论所有Java服务器端技术的网站.
http://www.jars.com - 提供Java评论服务. 包括各种framework和应用程序.
http://www.jguru.com - 一个非常棒的采用Q&A形式的Java技术资源社区.
http://www.javaranch.com - 一个论坛,得到Java问题答案的地方,初学者的好去处。
http://www.ibiblio.org/javafaq/javafaq.html - comp.lang.java的FAQ站点 - 收集了来自comp.lang.java新闻组的问题和答案的分类目录.
http://java.sun.com/docs/books/tutorial/ - 来自SUN公司的官方Java指南 - 对于了解几乎所有的java技术特性非常有帮助.
http://www.javablogs.com - 互联网上最活跃的一个Java Blog网站.
http://java.about.com/ - 来自About.com的Java新闻和技术文章网站
HttpClient http://jakarta.apache.org/commons/httpclient/ 处理http客户端的接口

原文地址
http://blog.csdn.net/Xviewee/archive/2007/12/17/1944374.aspx
posted @ 2011-05-05 15:31 ceaboat 阅读(1118) | 评论 (0)编辑 收藏
 

演示视频请点击

1.   概述

高效率开发、易用、功能稳定、执行效率高、维护成本低、需求变更是软件开发遵循的守则,然而现实中我们面临各种各样的问题:

1.     程序员A,程序员B开发同样的功能,理解不同、开发用时、及开发质量良莠不齐,延迟交付时间普遍。相反监督者需要花费更多精力与时间可以弥补,加大投入成本。

2.     后期维护成本高,如由于测试跟不上BUG检测不到、需求变更等。

3.     同行竞争的压力,如A公司开发模块实际时间10工作日、B公司开发模块实际时间15工作日,竞标会处于劣势。

4.     随着公司业务扩展,项目繁多,招揽人员越多、管理难度越大等因素日渐凸显,造成企业发展的瓶颈。

5.     人员的培养需要大量成本,与人员的不稳定性因素对企业造成损失较大,如人员请假、离职等。

6.     开发测试—QA—用户测试试运营运营,是软件开发中耗费成本巨大的一个循环过程链,制约企业发展。

上述是据个人经验总结,Db2view是针对上述问题的一个解决方案。

2.   Db2view架构

Db2view是以高效、稳定、易用、低成本维护为目的所研制的一套轻量级非入侵式、自动化开发平台。兼容多种架构,如SSHstruts—spring—ibatis等容易集成到系统,根据多年的行业经验,高效的针对各行业业务特点,最大化减少建设与维护成本。目前已在多个项目实施,不断完善。
2.1          Db2view总体架构图

           
    

            2.2          平台说明

        2.2.1              db2view核心层

Db2view:根据编写的SQL,在所有元素据中,勾选需要显示的元素据列,即可生成自定义显示列表。

如select school_id,school_name,school_code, school_manager from school

然后在配置界面勾选school_name, school_manager字段,则显示的列表为:

school_name

school_manager

广东广雅中学

黄光裕

广州先烈东小学

王兴东

查询:在SQL里涉及并且勾选的元素据字段中,可以选择是否作为查询的字段,勾选后该列成为查询项,如果是时间字段还可以进行时间区间查询的选择。

排序:列表中的每个字段都可以进行升序与降序的排列功能。

自定义字段名:对每个列名称进行界面配置,如勾选school_name、school_manager字段,可以对school_name定义显示列名为:学校名称、school_manager显示列名为:学校管理员,修改后列表显示如下:

学校名称

学校管理员

广东广雅中学

黄光裕

广州先烈东小学

王兴东

转义词:数据库中记录男女使用0,1表示,而界面需要显示为男女文字的信息,使用转义词可以达到效果。

删除:界面化配置是否需要删除功能,删除指定字段的表记录。

          2.2.2              扩展层

操作:所有列表均可以添加外部操作(如增加、批量删除)与行内操作(编辑、删除),由此构成一个完整的业务功能。(示例见演示视频)

 

数据导出:界面化配置是否需要excel数据导出功能,根据查询的条件显示的数据,可选择导出当前所见数据与所有满足条件的数据两个选择。

 

模板定制:界面化配置模板,方便为不同的客户需求定制不同的显示模板。

 

换肤:界面化配置皮肤,每个模板依据规范可以有不同的皮肤更换功能。

 

数据安全:加入访问权限控制规则,保障功能数据安全性。(待实现)

   3.   平台优缺点

  

  3.1          优点
(1)
高效率开发:db2view平台开发工具采用全界面配置,编写业务SQL,简单配置,即可完成。列表功能开发以分钟计时,15分钟可以完成一个高质量列表的功能开发。

    (2)易用性:界面编写SQL,然后配置即可得到一个界面友好,高质量的功能列表。将传统程序员需要熟悉各种复杂的技术框架解放出来,专注于业务逻辑,大大降低企业由于人员离职或其他情况所带来的损失。

    (3)功能稳定:所有功能使用统一内核,经过多个项目的迭代验证其稳定性、可靠性。

    (4)低成本维护:   所有的功能需要维护的只有业务SQL与配置文件,最大化的减少维护的成本。

比较现今流行的SSH架构开发流程:

维护成本是流程涉及的内容,成本花费高。

Db2view开发流程:

维护成本只有业务SQL与配置文件,易于维护。

    (5)快速响应需求变更:如业务更改字段名、添加或删除显示字段、

添加查询字段、功能删除等维护工作都能够在极短的时间内响应。
 

    (6)无需重启服务器:功能的生成与修改实时生效,无需重启服务器。

 


3.2          缺点
(1)   
平台仍需完善,暂不能够满足所有业务需求界面化

       (2)    平台操作友好性仍待提高,如转义词的添加、新添加配置等

    4.   平台支撑环境

数据库:ORACLE 10G以上版本

语言:JAVA

JDK版本:1.4以上

服务器:Tomcat,JBoss,Resin,WebSphere,WebLogic等主流服务器。

    5.   部署

根据开发模式分为两种部署方式。

面向服务式模式:

作为分布式服务器对外提供服务,生成功能链接嵌入应用系统。该模式的优点:

1.    对应用系统完全无入侵,100%轻量级开发。

2.    产品升级调试简单。

缺点:

1.    需要开放应用的数据库访问权限。

2.    涉及操作并有关联动作:如删除功能在A系统开发,B系统是Db2view,关联页面需要设置同域方能进行交互。

3.    安全性相对另一种模式低。

 

   组件模式:

作为组件集成到开发项目中,容易管理,安全性也高。

优点:

安全性高,可根据开发系统的权限要求做安全性控制

    缺点:

升级调试相对复杂。

5分钟生成功能例子,对此工具有兴趣者请加群:12990321.

posted @ 2010-04-01 17:47 ceaboat 阅读(1412) | 评论 (0)编辑 收藏
#1  世界上最经典的25句话

1.记住该记住的,忘记该忘记的。改变能改变的,接受不能改变的。

2.能冲刷一切的除了眼泪,就是时间,以时间来推移感情,时间越长,冲突越 淡,仿佛不断稀释的茶。

3.怨言是上天得至人类最大的供物,也是人类祷告中最真诚的部分。

4.智慧的代价是矛盾。这是人生对人生观开的玩笑。

5.世上的姑娘总以为自己是骄傲的公主(除了少数极丑和少数极聪明的姑娘例外)。

6.如果敌人让你生气,那说明你还没有胜他的把握。

7.如果朋友让你生气,那说明你仍然在意他的友情。

8.令狐冲说“有些事情本身我们无法控制,只好控制自己。”

9.我不知道我现在做的哪些是对的,那些是错的,而当我终于老死的时候我才知道这些。所以我现在所能做的就是尽力做好待着老死。

10.也许有些人很可恶,有些人很卑鄙。而当我设身为他想象的时候,我才知道:他比我还可怜。所以请原谅所有你见过的人,好人或者坏人。

11.鱼对水说你看不到我的眼泪,因为我在水里.水说我能感觉到你的眼泪,因为你在我心里。

12.快乐要有悲伤作陪,雨过应该就有天晴。如果雨后还是雨,如果忧伤之后还是忧伤.请让我们从容面对这离别之后的离别。微笑地去寻找一个不可能出现的你!

13.死亡教会人一切,如同考试之后公布的结果——虽然恍然大悟,但为时晚矣~!

14.你出生的时候,你哭着,周围的人笑着;你逝去的时候,你笑着,而周围的人在哭!一切都是轮回!!!! 我们都在轮回中!!!!

15.男人在结婚前觉得适合自己的女人很少,结婚后觉得适合自己的女人很多。

16.于千万人之中,遇见你所遇见的人;于千万年之中,时间的无涯荒野里,没有早一步,也没有晚一步,刚巧赶上了 。

17.每个人都有潜在的能量,只是很容易:被习惯所掩盖,被时间所迷离,被惰性所消磨。

18.人生短短几十年,不要给自己留下了什么遗憾,想笑就笑,想哭就哭,该爱的时候就去爱,无谓压抑自己。

19.《和平年代》里的话:当幻想和现实面对时,总是很痛苦的。要么你被痛苦击倒,要么你把痛苦踩在脚下。

20.真正的爱情是不讲究热闹不讲究排场不讲究繁华更不讲究嚎头的。

21.生命中,不断地有人离开或进入。于是,看见的,看不见的;记住的,遗忘了。生命中,不断地有得到和失落。于是,看不见的,看见了;遗忘的,记住了。然而,看不见的,是不是就等于不存在?记住的,是不是永远不会消失?

22.我们确实活得艰难,一要承受种种外部的压力,更要面对自己内心的困惑。在苦苦挣扎中,如果有人向你投以理解的目光,你会感到一种生命的暖意,或许仅有短暂的一瞥,就足以使我感奋不已。

23.我不去想是否能够成功,既然选择了远方,便只顾风雨兼程;我不去想,身后会不会袭来寒风冷雨,既然目标是地平线,留给世界的只能是背影。

24.后悔是一种耗费精神的情绪.后悔是比损失更大的损失,比错误更大的错误.所以不要后悔 。

25.日出东海落西山,愁也一天,喜也一天;遇事不钻牛角尖,人也舒坦,心也舒坦。
posted @ 2006-12-05 11:31 ceaboat 阅读(234) | 评论 (0)编辑 收藏

现象一:
         错误信息:
                 java.lang.SecurityException: sealing violation: can't seal package oracle.jdbc.driver: already loaded
         原因:
                 was启动的lib里存在多个ORACLE DRIVER。
         解决:
                 保留最新的一个驱动包解决。
         遗留问题:
                 开发环境使用TOMCAT发布无此问题,JBUILDER2006开发中包是有优先顺序的,即使存在多个
         相同的类,优先选择第一个找到的类。WAS在这方面显然存在不足,排异容错性不够强大。
现象二:
        错误信息:
               
Error 500: LinkageError while defining class: com.gzedu.eecn.structure.login.action.UserLoginAction Could not be defined due to: com/gzedu/eecn/structure/login/action/UserLoginAction (Illegal constant pool type) This is often caused by having a class defined at multiple locations within the classloader hierarchy. Other potential causes include compiling against an older or newer version of the class that has an incompatible method signature. Dumping the current context classloader
      
原因:
                 上传的文件已经损坏。重复试过很多次,发现本机器通过SSH上传过程中文件已经损坏。
         属于本机问题。
        解决:
               通过同事的机器上传文件解决
        总结:
                类似此问题出现的几率很小,可以认为是相同的环境,使用相同的方式做一件事情也有可能出现
       不同的效果。再次出现类似问题可以更快的定位错误点。
现象三:
        错误信息:
                  com.ibm.ws.jsp.translator.JspTranslationException: JSPG0227E: 转换 /login.jsp: 
/login.jsp(1,1) --> JSPG0145E: 未知 JSP 元素:jsp:directive.pagelanguage
         原因:
                  windows环境、tomcat作为服务器开发,部署到sit、unix环境,会出现页面不同的开发环境会
         有中文问题,或是说重复定义encoding的问题页面编码问题。
         解决:
            按照如下进行修改和配置;
                     
1. 对于不是被include的页面必须使用;
               <%@ page contentType="text/html;charset=GBK" pageEncoding="GBK" language="java" %>
               。 大写GBK
                     2. 对于被Include的页面必须使用如下;
               。<%@ page pageEncoding="GBK" language="java" %>
             注:在TOMCAT4.1.30-->was5.0,6.0出现此问题
        

posted @ 2006-01-25 15:09 ceaboat 阅读(2049) | 评论 (0)编辑 收藏
sun.jdbc.rowset.CachedRowSet是sun提供的缓存数据集的一个类(数据集持久化),对BLOG,CLOG不能支持,LOG的容量是4G,结果集里存在LOG字段缓存时会报java.lang.NumberFormatException: For input string: "4294967295"
据说sun对LOG的支持原来是2G,不晓得是否有支持4G的类。

对于原来使用的com.sun.rowset.CachedRowSetImpl深感疑惑此类在缓存number字段的时候如果SCALE没声明会报不能小于0的异常
posted @ 2005-12-09 09:57 ceaboat 阅读(849) | 评论 (0)编辑 收藏
1.GB2312支持拼音排序,GBK、GB18030不支持。2005年11月23日15:31:42
2.websphere5与6的区别:5对路径不需要/,而6必须要/,否则因为少了/找不到相应的配置文件
posted @ 2005-11-23 15:31 ceaboat 阅读(339) | 评论 (0)编辑 收藏

参与一个项目要做到:
1.项目中有你参与整个项目进展会顺利的多。体现你的重要性。
2.一个人的能力再强,精力是有限的。切记不可体现个人主义,充分发挥团队能力,协调、配合往往比
   技术重要性排前一个位置。
3.主动承担一些责任,对团队可提高士气融合的气氛、对个人当成一个磨练的机会。
4.注意项目中遇到的一些细小的问题。最不起眼的就是最能考验个人细心的程度,自己负责的事情要做到
   最好。
5.同一件事情不同的人处理效果不同。

posted @ 2005-11-10 00:21 ceaboat 阅读(431) | 评论 (0)编辑 收藏
通过URL来访问网站,action里request.getMothod()得到的GET.
而通过FORM来提交的则可以设置POST,可以通过这两种方
式的差异来做一些第一次访问与之后访问的一些个性化设置。
posted @ 2005-11-09 20:17 ceaboat 阅读(359) | 评论 (0)编辑 收藏

增加翻页接口,满足各种分页不同的界面化显示。
代码已经开发完,工具需要做小量修改,进期主要任务是编写使用手册。
2005年10月16日21:43:36

posted @ 2005-10-16 21:43 ceaboat 阅读(348) | 评论 (0)编辑 收藏
10.1到珠海过关的时候检查边防证,偶可是没那小本本,边警上来搜查,抓了4个人下去补办。(很多人都是没办的)看来穿着整齐是有点效果,人品好麻烦自然少
posted @ 2005-10-03 21:50 ceaboat 阅读(415) | 评论 (0)编辑 收藏

打算到上海浙江一带去放松,解决工作上的压力。现在是去不成了,国庆4天假,广州不是放松的好地方。白云山还算可以一去,只好改去珠海玩两天,吃点海鲜补偿补偿了

posted @ 2005-10-01 12:59 ceaboat 阅读(413) | 评论 (0)编辑 收藏
WASD支持热启动,修改代码保存服务器进行实时更新,CachedRowSet crs = new CachedRowSetImpl();缓存数据集出异常。服务器热启动与缓存机制之间有冲突。
posted @ 2005-10-01 12:54 ceaboat 阅读(434) | 评论 (0)编辑 收藏

                                                          测试源代码

CapabilityForConnection 主运行程序,读取配置文件init.properties、reference.properties初始化参数。调用POOLTEST(一次完整的测试用例),计算其平均时间与使用连接数

package com.cea.repository.test;

import
 org.apache.commons.logging.LogFactory;
import
 org.apache.commons.logging.Log;
import
 java.util.Properties;
import
 java.io.FileInputStream;
import
 java.io.InputStream;

public class
 CapabilityForConnection {
    
private static Log log = LogFactory.getLog(CapabilityForConnection.class
);
    
/**

     * 计算一次测试所消耗的时间
     
*/
    
public static long times = 0;
    
/**

     * 连接数
     
*/
    
public static long psize = 0;

    
public static void main(String[] args) throws
 Exception {
        
/**

         * 运行的次数
         
*/
        
int size = 1;
        
/**

         * 见POOLTEST说明
         
*/
        
int execsum = 0;
        
/**

         * 见POOLTEST说明
         
*/
        
int opencon = 0;
        
/**

         * execsum对应properties的命名
         
*/
        String execs 
= null;
        
/**

         * opencon对应properties的命名
         
*/
        String openc 
= null;

        
long sumtime = 0
;
        Properties prop 
= initProperty("reference.properties"
);
        Properties init 
= initProperty("init.properties"
);

        
if (init.size() > 0
) {
            Object o 
= init.get("init"
);
            size 
=
 Integer.parseInt(o.toString());
            execs 
= init.get("name0"
).toString();
            openc 
= init.get("name1"
).toString();
        }

        
for (int i = 0; i < prop.size() / 2; i++
) {
            execsum 
= Integer.parseInt(prop.getProperty(execs +
 i).toString());
            opencon 
= Integer.parseInt(prop.getProperty(openc +
 i).toString());
            sumtime 
= 0
;
            psize 
= 0
;
            log.info(
"" + (i + 1+ "组数据:"
);
            log.info(
"并发应用数:" + execsum + " 模拟连接数:" +
 opencon);

            String[] reference 
= {"" + execsum, "" +
 opencon};
            
for (int j = 0; j < size; j++
) {
                times 
= 0
;
                PoolTest.main(reference);
                sumtime 
+=
 times;
            }
            log.info(
"" + (i + 1+ "组数据共执行" + size + "次;平均耗时为:" +

                     sumtime 
/ (size * execsum) + "毫秒");
            log.info(
"平均使用" + psize / size + "个连接"
);

        }
    }

    
private static Properties initProperty(String filename) throws
 Exception {
        InputStream is 
= new
 FileInputStream(filename);
        Properties prop 
= new
 Properties();
        prop.load(is);
        
return
 prop;

    }
}

POOLTEST计算一次完整过程耗时,统计消耗的连接
package com.cea.repository.test;

import
 com.cea.repository.test.testdata.MainExecute;
import
 java.util.HashMap;
import
 java.util.Map;
import
 com.cea.repository.connection.PoolSupper;
import
 org.apache.commons.logging.LogFactory;
import
 org.apache.commons.logging.Log;
/**

 *
 * 

Title: 连接池性能测试


 *
 * 

Description: 测试不合理的利用连接对WEB应用所造成影响.


 *
 * 

Copyright: Copyright (c) 2005


 *
 * 

Company: 


 *
 * 
@author 小舟
 * 
@version
 1.0
 
*/

public class PoolTest extends Thread {
    
private static Log log = LogFactory.getLog(PoolTest.class
);
    
/**

     * 并发执行MainExecute的数量
     
*/
    
private static int EXECUTESUM = 35;
    
/**

     * 一次MainExecute执行所请求的连接数
     
*/
    
public static int CONNECTIONS = 3;
    
/**

     * 记录所使用的连接
     
*/
    
public static Map poolTestMap = new HashMap();
    
/**

     * 第sum次执行MainExecute所需要的时间
     
*/
    
public int sum = 0;

    
public void
 run() {
        
try
 {
            
long s =
 System.currentTimeMillis();
            com.cea.repository.test.testdata.MainExecute.main(
null
);
            
long t = System.currentTimeMillis() -
 s;
            CapabilityForConnection.times 
+=
t;
//
            if(CapabilityForConnection.times < t){
//
                CapabilityForConnection.times = t;
//
            }

//
            log.info("time" + (++sum) + ":" +
//                               (System.currentTimeMillis() - s));

        } catch (Exception ex) {
        }
    }

    
public static void main(String[] args) throws
 Exception {
        
if(args!= null && args.length>1
){
            EXECUTESUM 
= Integer.parseInt(args[0
]);
            CONNECTIONS 
= Integer.parseInt(args[1
]);
        }

        PoolSupper.initPool();
        startExec(EXECUTESUM);
        
//设定足够长的时间等待所有程序执行完,得到准确的并发执行所消耗的时间

        try {
            Thread.sleep(
6000
);
        } 
catch
 (InterruptedException ex) {
            ex.printStackTrace();
        }
        log.info(
"运行平均耗时:" + CapabilityForConnection.times/
EXECUTESUM);
        
//如果条件成立,证明连接没有被回收,只要存在一个相同的,就证明连接被重复利用了

        CapabilityForConnection.psize +=poolTestMap.size();
        
if (poolTestMap.size() ==
 EXECUTESUM) {
            log.info(
"不存在重复使用的连接,共创建" + poolTestMap.size()+ "个连接"
 );
        } 
else
 {
            log.info(
"共使用" + poolTestMap.size()+ "个连接"
 );
        }
        clear();
    }

    
private static void startExec(int
 EXECUTESUM) {
        
int i = 0
;
        
while (i <
 EXECUTESUM) {
            
if (i++ <
 EXECUTESUM) {
                
try
 {
                    
new
 PoolTest().start();
                } 
catch
 (Exception ex2) {
                }
            }
        }
    }
    
private static void
 clear() {
        poolTestMap 
= new
 HashMap();
    }


}

简单的不能再简单的测试代码:
package com.cea.repository.test.testdata;

import
 com.cea.repository.connection.drive.ConnectionFactory;
import
 java.sql.Connection;
import
 java.sql.Statement;
import
 java.sql.ResultSet;
import
 java.sql.PreparedStatement;
import
 java.util.HashMap;
import
 java.util.Map;
import
 java.util.List;
import
 java.util.ArrayList;
import
 com.cea.repository.test.PoolTest;
import
 com.cea.repository.connection.poolpository.PoolFactory;

/**

 * 
 * 

Title: 


 * 

Description: 


 * 

Copyright: Copyright (c) 2004


 * 

Company: cea


 * 
@author 小舟
 * 
@version
 1.0
 
*/

public class MainExecute {
    
public static void main(String[] args) throws
 Exception {
       testConnection();
    }

    
static void testConnection() throws
 Exception {
        
for (int i = 0; i < PoolTest.CONNECTIONS; i++
) {
            Connection con 
=
 PoolFactory.newInstance();
            
//这里的改变直接影响连接的复用

            Thread.sleep(50);
            PoolTest.poolTestMap.put(con.toString(), 
""
);
            con.close();
        }
    }

}

三个配置文件的内容:
init.properties文件
#运行的次数
init
=5

#并发执行MainExecute的数量所匹配的名字
name0
=execsum
#一次MainExecute执行所请求的连接数所匹配的名字
name1
=opencon

reference.properties文件
#过滤数据
execsum0
=10

opencon0
=1
#第一次测试数据
execsum1
=100
opencon1
=6
#第二次测试数据
execsum2
=85
opencon2
=9
#第三次测试数据
execsum3
=140
opencon3
=3

最后一个是pool-config.xml数据源配置:
xml version="1.0" encoding="GB2312"?>
<DataResources>
  
<ResourceParams dateIndentity="boat1">
    
<defaultAutoCommit>falsedefaultAutoCommit>
    
<initialSize>30initialSize>
    
<maxActive>40maxActive>
    
<minIdle>0minIdle>
    
<maxIdle>18maxIdle>
    
<maxWait>10000maxWait>
    
<username>forumusername>
    
<password>kingpassword>
    
<driverClassName>oracle.jdbc.driver.OracleDriverdriverClassName>
    
<url>jdbc:oracle:thin:@192.168.1.3:1521:gzesturl>
    
<removeAbandoned>trueremoveAbandoned>
    
<removeAbandonedTimeout>10removeAbandonedTimeout>
    
<logAbandoned>truelogAbandoned>
  
ResourceParams>
DataResources>
posted @ 2005-09-26 22:36 ceaboat 阅读(1645) | 评论 (0)编辑 收藏

         影响性能的测试报告(数据库版)

引言

如需转载,请与笔者联系

 

前提:项目组里无用到SPRING进行事务的管理。项目里以功能划分到每个人手里,

形成了BODAOACTIONVIEW都是单人负责。在DAO中每个动作都以

      封闭式的形式存在。

问题:造成事务的不连贯性。功能是做出来了,性能问题迟早暴露。

测试:主要针对程序频繁请求数据库连接对WEB应用所造成影响做一个测试。

 

 

先做必要的说明,一步步引入正题,先从性能瓶颈开始:

性能瓶颈

所有的应用程序都存在性能瓶颈,为了提高应用程序的性能,就要尽可能的减少程序的瓶颈。以下是在JAVA程序中经常存在的性能瓶颈。

pingjing.jpg
了解了这些瓶颈后,就可以有针对性的减少这些瓶颈,从而提高JAVA应用程序的性能

 

数据库连接池工作原理

关于连接池的实现原理测试方案:

经过资料的收集与APACHE DBCP里连接池的查阅,对现有的连接池工作

原理有两种方式:

1.        数据库预先设置配置好的连接数。待得到用户请求连接,传出一个连接,而后为了保持供应数再提前创建连接,即提前预备连接数供请求。比如:

5个通行道代表最大激活的连接数,最小2个闲置连接数。也就是说连接池里始终预备了2个可随时提供的连接,连接的创建开销是比较大的,连接池的存在就是了能够最小化的解决创建所等待的时间。

  1            O

  2            O

  3            *

  4            *

  5            *

  如上图,当1分配出去时由于池中连接数剩一个,为保持最小闲置,会自动创建一个新的连接以防止再次请求等待创建的时间。这样确实减少了等待的时间,但是数据库创建的开销方面并未得到解决。如果把1-5比喻成汽车,那么这种情况下每量车都是一次性使用。1被请求后下一个连接将是6来接替。那么如何能够重复利用1减少数据库开销。于是引出第二种方式。

 

2.        回收使用完后的连接,放回到池中进行循环利用。这么做必须能保证2

   .  使连接能够保持有效的回收。

   .  约束使用者使用释放的动作,而不是直接把连接close.

 

本人使用的是APACHE DBCPBasicDataSource的连接池基本实现,

经过代码与测试结果显示,其工作方式是基于二的。

 

BasicDataSource测试用例

请看测试用例

测试结果:


2组数据:

并发应用数:100 模拟连接数:6

运行平均耗时:2956

共使用51个连接

运行平均耗时:3391

2共使用52个连接

运行平均耗时:2616

共使用47个连接

运行平均耗时:3377

共使用41个连接

运行平均耗时:3673

共使用46个连接

2组数据共执行5;平均耗时为:3229毫秒

平均使用47个连接

 

3组数据:

并发应用数:85 模拟连接数:9

运行平均耗时:4830

共使用53个连接

运行平均耗时:3247

共使用49个连接

运行平均耗时:4116

共使用40个连接

运行平均耗时:4070

共使用43个连接

运行平均耗时:4053

共使用54个连接

3组数据共执行5;平均耗时为:4063毫秒

平均使用47个连接

 

4组数据:

并发应用数:140 模拟连接数:3

运行平均耗时:2076

共使用47个连接

运行平均耗时:3104

共使用51个连接

运行平均耗时:2048

共使用43个连接

运行平均耗时:2421

共使用50个连接

运行平均耗时:2751

共使用50个连接

4组数据共执行5;平均耗时为:2480毫秒

平均使用48个连接

 

每次测试的结果都可能不同,但是所得到的结论是一致的。数据显示不合理的请求使用连接严重的影响应用所能承受的并发数量,响应的时间也因此受到影响。

 

目前普遍存在的问题

没有把事务控制好,一般会出现以下的情况:

事务(){

  流程1();

  流程2();

}

可以看出流程12里都是单独创建连接,并在自己的流程里完成操作。

如果在流程2里出现异常,那么流程1所做的操作是不可恢复的。

如果能控制在事务范围内,如:

事务(){

  Connection con;

  流程1(con);

  流程2(con);

  con.close();

}

那么数据库少提供一个连接,事务的完成性也得到体现。在并发数量大的时候,

效率上就有非常明显的区别。

解决方案

1.  尽量保持少的请求

DAO中有update()方法,则应再扩展一个方法update(Connection conn)

在业务逻辑事务里调用update(Connection conn),一般情况下调用update()

2.  对于数据不变的情况采用缓存技术,或部分缓存技术。

      可参照一些相关的开源的项目(JIVE)。

posted @ 2005-09-25 17:21 ceaboat 阅读(1657) | 评论 (4)编辑 收藏
把ent.slip放入\Borland\JBuilder2006\license里
posted @ 2005-09-24 13:45 ceaboat 阅读(808) | 评论 (2)编辑 收藏

1.运行环境:
JDK,ORACLE9i以上,CASTOR包。建议使用JBUILDE
工具进行开发
2.使用环境:
采用ORM(关系对象映射)操作数据库数据,适用于Application与WEB方式下的开发。

3.功能:
    提供查询,更新,删除,插入(没实现主键自动生成),(分页暂时没实现)。4.使用步骤:
首先在数据库建立一个cat表,字段为cat_id;name;sex;weight;类型1,4为数字型,2,
3为字符串型。

其次建立两个配置文件(由自己定义文件名称):
repository.xml配置信息:
<?xml version="1.0" encoding="UTF-8"?>
<Repository>
 <TableDesc execid="CAT" identifyField="CAT_ID">
  <table>CAT</table>
  <condition />
 <FieldDesc name="CAT_ID" fieldType="java.lang.String" >
  <title>CAT_ID</title>
  </FieldDesc>
 <FieldDesc name="NAME" fieldType="java.lang.String" >
  <title>NAME</title>
  </FieldDesc>
 <FieldDesc name="SEX" fieldType="java.lang.String" >
  <title>SEX</title>
  </FieldDesc>
 <FieldDesc name="WEIGHT" fieldType="java.lang.Long" >
  <title>WEIGHT</title>
  </FieldDesc>
  </TableDesc>
</Repository>
配置文件的设计说明如下:
TableDesc 表示一个表的声明。
Execid 是类名一般情况下最好和表名一致(容易找到对应关系),但是不允许有下划线出现。注意这个类名不是全路径。
DentifyField 表中的主键,如果是复合主键则以逗号相隔开
Table 数据库表名
<FieldDesc name="SEX" fieldType="java.lang.String" >
  <title>SEX</title>
  </FieldDesc>
这里是表中字段的描述,name是字段名。 fieldType 是数据库字段对
应java中的类型,只有4中类型可填充:java.lang.String,
java.lang.Long, java.util.Date, java.lang.Double
title可要可不要.如果存在多个表,那么就在</TableDesc>和
</Repository>之间加入表描述。

pool-config.xml配置信息:
<?xml version="1.0" encoding="GB2312"?>
<ResourceParams>
<maxActive>10</maxActive>
<maxIdle>5</maxIdle>
<maxWait>10000</maxWait>
<username>test</username>
<password>test</password>
<driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName>
<url>jdbc:oracle:thin:@192.168.0.90:1521:forecast</url>
<removeAbandoned>true</removeAbandoned>
<removeAbandonedTimeout>60</removeAbandonedTimeout>
<logAbandoned>true</logAbandoned>
</ResourceParams>
把上述信息保存为XML文件。对这个文件不多做说明了。

确定两个文件已经存在,接下来就是要创建表CAT。
还有表所对应的BEAN。
下面是我在Hibernate的一个例子中建立的VO。(借用)
package com.cea.boat.dao;
  import java.util.*;
  public class Cat implements Cloneable  {
    //Declare Field
    private java.lang.String  catId;
    private java.lang.String  name;
    private java.lang.String  sex;
    private java.lang.Long  weight;
    //Get Method
    public java.lang.String getCatId() {
       return catId;
    }
    public java.lang.String getName() {
       return name;
    }
    public java.lang.String getSex() {
       return sex;
    }
    public java.lang.Long getWeight() {
       return weight;
    }
    //Set Method
    public void setCatId(java.lang.String catId) {
       this.catId=catId;
    }
    public void setName(java.lang.String name) {
       this.name=name;
    }
    public void setSex(java.lang.String sex) {
       this.sex=sex;
    }
    public void setWeight(java.lang.Long weight) {
       this.weight=weight;
    }
  public Object clone() {
    Object o = null;
    try {
      o = super.clone();
    }
    catch (CloneNotSupportedException ex) {
      System.out.println(o);
    }
    return o;
  }
  public boolean equals(Object obj) {
    Cat o = (Cat)obj;
    boolean result = true
        && (catId == o.catId || catId.equals(o.catId))
        && (name == o.name || name.equals(o.name))
        && (sex == o.sex || sex.equals(o.sex))
        && (weight == o.weight || weight.equals(o.weight))
    ;
    return result;
  }
  }
到此已经完成了该做的事了,下面是一个使用的例子。

l查询方式:
例子:
Void testQuery() throws Exception{
    {
System.setProperty(Const.RUN_KEY, Const.POOL_FACTORY_KEY);
      System.setProperty(Const.CONFIG_PATH,
                         "E:/project/CEAConnection/pool-config.xml");
      System.setProperty(Const.REPOSITORY_CONFIG_PATH,
                         "E:/project/CEAConnection/repository.xml");
}

ConnectionManage connectionManage = new ConnectionManage();
 connectionManage.activity("com.cea.boat.dao.Cat cat");
  
   Query Query=connectionManage.createQuery(“cat. Catid=’1’ ”);
    while (Query.hasNext()) {
      Object[] objects = Query.next();
      Cat cat = (Cat) objects[0];
    }
 connectionManage.close();
}
说明:
在WEB中使用只需要在网站启动时声明一次即可。
{
//指明使用连接池
System.setProperty(Const.RUN_KEY, Const.POOL_FACTORY_KEY);
//连接池参数配置文件
      System.setProperty(Const.CONFIG_PATH,
                         "E:/project/CEAConnection/pool-config.xml");
//配置文件指定
      System.setProperty(Const.REPOSITORY_CONFIG_PATH,
                         "E:/project/CEAConnection/repository.xml");
}

   声明一个连接管理者,管理数据库资源,事务的起始,它的生命周期最好是在一个事务结束就完结,当然你也可以在这个事务完结时继续用这个实例,来创建下一个事务的开始。不建议如此使用。
    ConnectionManage DataManage = new ConnectionManage();
   
激活要使用类(在配置中必须有Cat),类名为全路径如果要使用多个对象,则对象间要用逗号相隔开
connectionManage.activity("com.cea.boat.dao.Cat cat");

这里只需要给出SQL查询条件比如SQL中是select * from cat cat where cat.Catid=‘1’那么 select * from cat cat where 这里后台已经帮你完成,你需要做的就是把条件完成,如果没有条件则为空.
Query Query = connectionManage.createQuery(“cat. Catid=’1’ ”);


   Query.hasNext()的作用相当于resultset.next()查看是否还存在记录,Query.next()返回一个对象数组这里如果activity的是多个对象,那么objects里会顺序的存储相应的对象实例,使用的时候强制转化就可以了。
while (Query.hasNext()) {
      Object[] objects = Query.next();
      Cat cat = (Cat) objects[0];
  }

使用完毕,释放使用的数据库资源
 connectionManage.close();

l新增方式:
  由于没有主键自动生成,因此主键暂时只能由自己来维护,要保证catid为111的在表里不存在,否则会出现异常。
Void testInsert() throws Exception{
Cat cat = new Cat();
cat. setCatId(“111”);
    cat. SetSex(“F”);
    cat. setName(“catm”);
    ConnectionManage cm = new ConnectionManage();
    cm.create(cat);
    cm.commit();
cm.close();
}

l更新方式:
表里已经存在catid为111的猫,否则查不到这条记录就更新不了信息
Void testUpdate() throws Exception{
Cat cat = new Cat();
cat. setCatId(“111”);
    cat. SetSex(“F”);
    cat. setName(“catmm”);
    ConnectionManage cm = new ConnectionManage();
    cm.update(cat);
    cm.commit();
cm.close();
}

l删除方式:
删除方式比较简单,只要给出对象,并且主键值不为空,就可以删除表中记录。
Void testDelete() throws Exception{
Cat cat = new Cat();
cat. setCatId(“111”);
    ConnectionManage cm = new ConnectionManage();
    cm.delete(cat);
    cm.commit();
cm.close();
}

posted @ 2005-09-15 23:41 ceaboat 阅读(423) | 评论 (0)编辑 收藏