OO在查询统计中的运用 请教Banq老师


虽然自己学习Java语言有一段时间了,但是自己发现对Java这门面向对象的编程语言的面向对象特性虽有一定的了解,但是却无法在实际编程中运用它。
今天自己做了一个简单的查询统计小系统,由于没有运用统计报表,可能大家认为很简单,但是今天我想说的不是用不用统计报表,而是对于我自己实现的该查询统计功能的实现方法。我也知道该方法十分丑陋,但是由于商业项目时间不够,暂时也就这样了。
下面简单说一下功能。这个功能设计到四张表,分别为:gongchengxinxi,yaoqingzhaobiao,zhijiefabao,erjifenbao.(工程信息,邀请招标,直接发包,二级分包)
前台页面:用户输入各种查询条件,但是有的可以不输入
后台:处理用户输入进来的各种条件,组合成sql语句。
最后返回给前台显示。
现在的问题是由于前台有的用户可以不输入条件,有的输入条件,还有就是输入的条件不同,我要反复的进行if else判断,形成了非常庞大的代码块,不仅容易出错,而且今后难以维护。
下面是我的代码
1、前台
<form name="form1" method="post" action="/zhaotoubiao/gongchengchaxun.do?action=add">
<br>

<br>

<br>
<div align = "left">
选择招标方式(可多选):
<br>
<input type="checkbox" name="gongkai" value="公开招标">公开招标
<input type="checkbox" name="yaoqing" value="邀请招标">邀请招标
<input type="checkbox" name="zhijie" value="直接发包">直接发包
<input type="checkbox" name="erci" value="二级分包">二级分包
<br>
<br>
选择时间属性(为单选):
<br>
<label>
<input type="radio" name="shijianfangshi" value="dengji">
登记时间</label>

<label>
<input type="radio" name="shijianfangshi" value="baoming">
报名时间</label>
<label>
<input type="radio" name="shijianfangshi" value="zhongbiao">
中标时间</label>

<br>

<input name="begin" type="text" size="8"
onClick="JSCalendar(this)"
onBlur="this.style.backgroundColor=''" /><font color="red">(不包括该天)</font>

<input name="end" type="text" size="8"
onClick="JSCalendar(this)"
onBlur="this.style.backgroundColor=''" /><font color="red">(包括该天)</font>
<br>
<br>
选择工程类别(可多选):
<br>
<input type="checkbox" name="fangwu" value="房屋建筑">房屋建筑
<input type="checkbox" name="shizheng" value="市政道路">市政道路
<input type="checkbox" name="yuanlin" value="园林绿化">园林绿化
<input type="checkbox" name="zhuangshi" value="装饰装修">装饰装修

<input type="checkbox" name="jianshe" value="建设监理">建设监理
<input type="checkbox" name="jidian" value="机电安装">机电安装
<input type="checkbox" name="caigou" value="设备采购">设备采购
<input type="checkbox" name="qita" value="其它">其它


</div>
<br>
<br>
<div id="div">
<input name="add" type="submit" class="botton" id="add2"
value="提 交" />

<input name="Submit2" type="reset" class="botton" value="放 弃" />
</div>
</form>


2、后台:
GongchengchaxunForm myform = (GongchengchaxunForm) form;// TODO Auto-generated method stub
// 招标方式
String gongkai = myform.getGongkai();
String yaoqing = myform.getYaoqing();
String zhijie = myform.getZhijie();
String erci = myform.getErci();
// 时间性质
String shijianfangshi = myform.getShijianfangshi();
// 具体时间
String begin = myform.getBegin();
String end = myform.getEnd();
// 工程类别
String fangwu = myform.getFangwu();
String shizheng = myform.getShizheng();
String yuanlin = myform.getYuanlin();
String zhuangshi = myform.getZhuangshi();
String jianshe = myform.getJianshe();
String jidian = myform.getJidian();
String caigou = myform.getCaigou();
String qita = myform.getQita();

System.out.println(shijianfangshi);
System.out.println(gongkai+" "+yaoqing+" "+zhijie+" "+erci+" "+shijianfangshi);
System.out.println(fangwu+" "+shizheng+" "+yuanlin+" "+zhuangshi+" "+jianshe);
System.out.println();

boolean kong1 = true;
boolean kong2 = true;
StringBuilder sql ;

// /登记时间
if(shijianfangshi.equals("dengji")){
sql = new StringBuilder();
if(gongkai!= null){////公开招标
sql.append(" select id,gcbh,gcmc,zbxs,xmlx,tjrq from gongchengxinxi where (");
kong2 = false;
//工程类别
if(fangwu != null){
sql.append(" xmlx = '"+fangwu+"'");
kong1 = false;
}
if(shizheng != null){
if(kong1==false){
sql.append(" or xmlx = '"+shizheng+"'");
}else{
sql.append(" xmlx = '"+shizheng+"'");
}
kong1 = false;
}
if(yuanlin != null){
if(kong1==false){
sql.append(" or xmlx = '"+yuanlin+"'");
}else{
sql.append(" xmlx = '"+yuanlin+"'");
}
kong1 = false;
}
if(zhuangshi != null){
if(kong1==false){
sql.append(" or xmlx = '"+zhuangshi+"'");
}else{
sql.append(" xmlx = '"+zhuangshi+"'");
}
kong1 = false;
}
if(jianshe != null){
if(kong1==false){
sql.append(" or xmlx = '"+jianshe+"'");
}else{
sql.append(" xmlx = '"+jianshe+"'");
}
kong1 = false;
}
if(jidian != null){
if(kong1==false){
sql.append(" or xmlx = '"+jidian+"'");
}else{
sql.append(" xmlx = '"+jidian+"'");
}
kong1 = false;
}
if(caigou != null){
if(kong1==false){
sql.append(" or xmlx = '"+caigou+"'");
}else{
sql.append(" xmlx = '"+caigou+"'");
}
kong1 = false;
}
if(qita != null){
if(kong1==false){
sql.append(" or xmlx = '"+qita+"'");
}else{
sql.append(" xmlx = '"+qita+"'");
}
}
//时间范围
if(begin != null){
sql.append(" and tjrq > '"+begin+"'");
}
if(end != null){
sql.append(" and tjrq <= '"+end+"'");
}
kong1 = true;
sql.append(")");
}
//结束公开招标
if(yaoqing != null){///邀请招标
if(kong2 = false){
sql.append(" union select id,gcbh,gcmc,zbxs,xmlx,tjrq from yaoqingzhaobiao where(");
}else{
sql.append(" select id,gcbh,gcmc,zbxs,xmlx,tjrq from yaoqingzhaobiao where(");
}

if(fangwu != null){
sql.append(" xmlx = '"+fangwu+"'");
kong1 = false;
}
if(shizheng != null){
if(kong1==false){
sql.append(" or xmlx = '"+shizheng+"'");
}else{
sql.append(" xmlx = '"+shizheng+"'");
}
kong1 = false;
}
if(yuanlin != null){
if(kong1==false){
sql.append(" or xmlx = '"+yuanlin+"'");
}else{
sql.append(" xmlx = '"+yuanlin+"'");
}
kong1 = false;
}
if(zhuangshi != null){
if(kong1==false){
sql.append(" or xmlx = '"+zhuangshi+"'");
}else{
sql.append(" xmlx = '"+zhuangshi+"'");
}
kong1 = false;
}
if(jianshe != null){
if(kong1==false){
sql.append(" or xmlx = '"+jianshe+"'");
}else{
sql.append(" xmlx = '"+jianshe+"'");
}
kong1 = false;
}
if(jidian != null){
if(kong1==false){
sql.append(" or xmlx = '"+jidian+"'");
}else{
sql.append(" xmlx = '"+jidian+"'");
}
kong1 = false;
}
if(caigou != null){
if(kong1==false){
sql.append(" or xmlx = '"+caigou+"'");
}else{
sql.append(" xmlx = '"+caigou+"'");
}
kong1 = false;
}
。。。。。。。。。。。。。。。。。
[该贴被jiyanliang于2007年08月30日 19:26修改过]

Banq老师
我把代码都贴出来,只是为了说明自己的痛苦。
我想运用Java这门面向对象的语言,还有其他好的实现方法吗。
请教。
还是要用到设计模式,或者我本来的设计思路就错了

因为你这是围绕数据库SQl编程,就会形成这样很痛苦的代码。如果能用就用吧,当然问题就是维护起来小心翼翼,会得神经质。

需要重新换一个思路使用OO分析设计你的系统。
画出用例图和状态图。你这个案例主要是跟踪状态,可能需要状态模式。

虽然你代码列出来来,但是不太容易看出你这个查询系统的需求,这也是传统过程编程的缺点,需要详细需求描述。

大概实现思路可能会这样:
因为你这是查询系统,根据Evans DDD的repository,首先从数据库仓库获得一些主要实体对象,比如工程信息,邀请招标,直接发包,二级分包这四个,然后,根据输入事件和条件,进行具体对象合成,输出结果。

[该贴被banq于2007年08月31日 10:09修改过]

其实就是动态SQL查询,这和OO有一毛钱的关系吗?

你可以使用ibatis 这样的工具,具有这个功能。

如果自己写sql,那就避免不了 if 判断。

至于

“首先从数据库仓库获得一些主要实体对象,比如工程信息,邀请招标,直接发包,二级分包这四个,然后,根据输入事件和条件,进行具体对象合成,输出结果”

我觉得这根本和楼主说的是一分钱关系也没有。

因为之前看过Banq老师的一篇<你还在用 if else?>对自己的触发很大,现在每当我在用if else 的时候总感觉自己还有很多要做,所以就想寻找面向对象的解决方法。
感谢Banq的指点,同时也感谢楼上的提醒。