赛迪网技术社区 » 数据库综合技术专区 » 构建通用的数据库插入操作 转到动态网页
--> 本页主题: 构建通用的数据库插入操作 返回 | 悬赏 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题
dblearn




用户名: dblearn
级别: 工程师
精华: 9
发帖: 97
经验值: 274 点
积分: 548 分
贡献值: 0
注册时间:2006-08-10


构建通用的数据库插入操作


  在做一些简单的JDBC的API应用时,就老想只用一个方法向数据库不同的表做插入操作,省得用一大堆的insert语句。访问者模式可以实现 [D{=ZOMKA8  
l,q 09fd(  
对未知的类进行操作,于是就用了这个简化了的模式的实现方案。请高手指正。 在使用访问者模式之前先叙述一点概念性的东西。 8=A/1-r}  
  静态类型的概念:变量被申明时的类型。实际类型:变量的实际类型。  =W~5F  
  比如 Object object=new String(); object静态类型是Object,实际类型是String.观察者模式是一个比较难理解的模式,在理解观察者模 QkLb7^@8R  
-&r!7>oiX  
式之前当然应该先理解双重分派的概念。 9Sl @CX)  
  java语言支持静态的多分派跟动态的单分派。java通重载支持静态的多分派。书上的例子: K] T36Nt  
W>6KDDi  
<CENTER><ccid_nobr> {t[mwuPaA  
<table width="400" border="1" cellspacing="0" cellpadding="2" 3^WU4@^U  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> J V=@\ oJ  
<tr> vk*pj 5  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> XA'YEGXI(  
  <pre><ccid_code> l[Nz?j3Y  
DJw7}b\ S  
[hms8(ve-  
public class Mozi { 8ouynGP  
  h@AN'@s  
  public void ride(Horse h){ rYeRV]|  
    System.out.println("ridding a horse"); b?^Tn/S  
  } 0`H.ZqZHQ  
  public void ride(WhiteHorse w){ ##D1AWr  
    System.out.println("ridding a white horse"); D~L\0a%\  
  } Kw/'s95?B  
  public void ride(BlackHorse b){ OIvx8@Jh]  
    System.out.println("rdding a black horse"); 5PnJ&&  
  } `E[WQw d  
yY'1G2  
  public static void main(String[] args){ ,E{1(9  
    Mozi mozi=new Mozi(); bgf]dpK'K  
    Horse w=new WhiteHorse(); llgccg%lB  
    Horse b=new BlackHorse(); k7DXTd0#  
    mozi.ride(w); *;2~D)m =  
    mozi.ride(b); kKSEg] *  
  } ^}g)py-R  
} ew l(T  
$=o1Z}'  
</ccid_code></pre> Q'a<qV! 6  
  </td> pN]kW1.  
</tr> >J|jA{a  
</table> u^w)uXzc  
</ccid_nobr></CENTER> 0eov.Ufy  
F)fk2K z-L  
  程序打印输出: sfC1b^v  
  ridding a horse i$. bm:.F  
  ridding a horse |.\q-H>$  
  原因就是对两次ride方法的调用传入的参量不同,但是它们的静态类型是一样的,都是 Horse;这个过程在编译时期就完成了。java通过方 L<VIE4ft  
=Pr|Nz  
法置换支持动态分派。比如 String s1="ab"; Object o=s1+"c"; String s="abc";o.equals(s) 打印true o.equals()方法执行的是String类 vDG`l  
&YK f3J?  
的equals()方法.java调用对象的真实类型的方法,这就是动态分派。 }xG~{Nk~  
}W.Qa37kU  
8j8Wo>H  
双重分派: ,/7H qR e  
%Jq`8nzXmF  
<CENTER><ccid_nobr> kP @Gf;k  
<table width="400" border="1" cellspacing="0" cellpadding="2" ;]ea<(X  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> E ac P,[  
<tr> F}; WI  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> .LNzPdA 5  
  <pre><ccid_code> h+'V {de7  
)jti$z7  
]md  
public abstract class Vistor{ cp}Iy ] u  
G?k \7`=  
protected void processStrig(Object e){ /WQFh  
if(e instanceof String){ 0 i3*Cj  
  String tmp=(String) e; iiaF:l%Rvq  
  String need="'"+e+"'"; ^O? ^W{  
  System.out.println(nedd); ~W5?I+Bv  
  }else if(e instanceof Integer){ _5 F%Z?}  
    String need=e.toString(); n(D9amAA  
    System.out.println(need); U^-p5c gW  
  }else if(e instanceof Date){ 0I!DW7/<z  
        Date tmp=(Date) e; D"nXo>AM=  
        String need="'"+tmp.toString()+"'"; }&K2jd v5  
    } \,$+u~  
    .... @a(<Sxv_O  
  } dm`"r!6*  
i2I[J$J&  
} i(fzX:J P  
@WU4%  
public class ConcreteVisitor extends Visitor{ MO1:H?D  
97>DR:Ow[  
protected void processString(Object e){ /8;L6N  
  super.processString(e); L]p+{  
  }   u0C RCvB  
} CO8OV  
ID2B_^bc  
z'<nO  
</ccid_code></pre> e 'nf<D  
  </td> e{ Pp8l%S  
</tr> ]A8g\^  
</table>  QOeV r  
</ccid_nobr></CENTER> /8sn kq{  
U uc>  
  方法的调用Visitor v=new ConcreteVisitor(); v.processString(new String("tt")); #pvv9S<y  
v.processString()方法在调用的时候会检察v的真实类型,调用真实类型的方法,这个时候就发生了一动态的单分派过程.当子类调用超类的方 bN>YXk_NJ  
A*5c^mNGG  
法的时候明显的根据instanceof判断的真实类型去执行不同的方法,又发生了一次动态分派的过程.这个就是双重分派的实现。这种方法实现的 M,s-~ecj7  
+ _vaCw#  
程序比较冗长和容易出错。 UR*/%W=M  
W . J31  
  “返传球”方案: Y7J3 h  
>ZJrEf#b  
<CENTER><ccid_nobr> :/T%F(MV  
<table width="400" border="1" cellspacing="0" cellpadding="2" aC_z# oQI  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> xT3 )U:  
<tr> V08vj$C&k  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> 8s* -\  
  <pre><ccid_code> 5:AX&2]%  
)TyUG KfO  
public abstract class Vistor{ |*A!y"VC*J  
ih#V%$w:Z  
  public abstract String processStrig(Object e); &nqG+MUa  
uI^YwL[  
} yPA|)}V  
>-zftj/  
public class ConcreteVisitor extends Visitor{ |ww,Ai\K  
.3WQt Z8  
public String processString(WrapperString e){ "cMGfqTZ  
  String tmp= t.toString(); t-;6hF]YV  
  System.out.println(tmp); #c#wo+9/'  
  }   LZ075j!  
1@lOb=  
public String processInteger(WrapperInteger e){ %>"/*@Vo3'  
  String tmp=e.toString(); % 98zB  
  System.out.println(tmp); <;J!ivp$  
]jIee *G  
  } qJb0ecjF  
kK_rqgy  
} hU7:NCM  
vA V 54  
public class abstract Wrapper{ ?w3"L}K1&  
public abstract String processString(Vistor v); [25N"O  
} ^Q/E.H!f@  
Dqu:6{_  
public class WrapperString extends Wrapper{ L ,QsyvA  
a{Qbg`:H  
public String processString(Vistor v){ #4Y k*Lh  
  v.processString(this); P 3agt1  
  } C:n6I`2  
public String toString(){ BTthsLEdb  
  ... bG>$<S  
  } @MORy \*f  
} Y6nm}sX?  
aT}u `OSV  
public class WrapperInteger extends Wrapper{ 7 HsV&a7,  
  public String processInteger(Visitor v){ p5qBwTixO  
  v.processString(this); ,Yp]l  
  } IAkAtd  
  public String toString(){ 2pH( |4  
  ... ETPq>(a)  
  } pQH ^eIx  
} f (:)VcI  
$H*V5SSPg  
</ccid_code></pre> EupD@A  
  </td> M*] %'C>  
</tr> y,o.$NP,  
</table> W|/-c C6O  
</ccid_nobr></CENTER> w\; { f  
FPG!<\&  
  方法的调用: c`HJ:ggziN  
o74 aIg)  
<CENTER><ccid_nobr> U[bgf3;D  
<table width="400" border="1" cellspacing="0" cellpadding="2" "76+Mr#9  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> m]Q z/b  
<tr> }kXpm gy  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> _e[<Mdi'o  
  <pre><ccid_code> jN9;n63A  
L#Kb+1Zg  
Visitor v = new ConcreteVisitor(); at"@x'  
Wrapper wrapper= new WrapperString(); rJ-UnNGf]  
wrapper.processString(v); xfSkM  
</ccid_code></pre> PjU3.~b#  
  </td> B"V@4  
</tr> B<bM4\yPl  
</table> # ZAyJ:  
</ccid_nobr></CENTER> qZN]MH0  
_b0s..N+LD  
  当wrapper.processString()方法执行的时候会检察wrapper的真实类型,这个就产生了一次动态单分派,processString()里面的语句v.pr )Yb Dkd  
m=F8$ &  
ocessString()在执行的时候也会检察v的真实类型,动态双重分派就发生了。访问者模式的核心就是“返传球“方案的双重分派。其示意性 \~*\fC8y  
",FtJ+!  
类图:(注:虚线箭头划错了) /p;s!(l&A  
D^}dG  
Bx:[=][  
  在一个方法内实现向不同的表插入不同数据的具体实现方案(简化了的):因为整个方案里只需要一个访问者对象,因此使用简化了的访问 NF.!:0  
}$7\"'Fq  
者模式。因为java基本类型及对应的类是不变模式的实现:因此包装一下这些基本类型和类并实现访问者模式需要的方法。 4^:wt]H  
2U!1UY h  
<CENTER><ccid_nobr> A0'Xw{~  
<table width="400" border="1" cellspacing="0" cellpadding="2" yH9E[.(M9  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> Y >TdY  
<tr> 7w=$;D]n*}  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> :W%~79k  
  <pre><ccid_code> $-Yt|W  
public abstract class Wrapper { /<BM%Q  
  public Wrapper() { 8b'r>YKH  
  } 2l88l`)5  
  public abstract String action(Visitor visitor); tGC@^=)s)  
:ob':G'[  
} SP~J\4B  
3fK"i  
包装Date类: ,#C["Z/G^  
import java.util.Date; ^7 pdW^$  
public class WrapperDate extends Wrapper { ?#~f15>k  
  private Date date; +i:y*g^~  
  public WrapperDate(Date date) { 7 [u yV  
    this.date=date; 32Z }[_?  
  } L=;'1,]  
  public String action(Visitor visitor){ Aj*/ToiZQ  
      return( visitor.visit(this)); EI=Ux|j<H  
  } 6|Hz`D6b  
3^ (VVAN  
  public String toString(){ =/ T}f7\~  
    if (date==null){ /d)eJBR  
        return "null"; 4Q*H?%j  
    } ~".i by  
    return "'"+date.toString()+"'"; pgW "m=  
  } 0?E#'FLvj  
Ox;ESxcXr  
} !uao}JY  
A;#R(!w.+  
</ccid_code></pre> ]P0s:-(G  
  </td> Z{ ]DFy  
</tr> e\pbr3Y}|  
</table> 2_n<  
</ccid_nobr></CENTER> WS}0S<+B  
bIeuZ>e0\  
包装Integer类: FQ'{X ~}  
Q|V(.d^Ac  
<CENTER><ccid_nobr> XK _7GK(}"  
<table width="400" border="1" cellspacing="0" cellpadding="2" nS%MVX  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> /41y`S  
<tr> [0p^AN`G''  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> oGWV%;=}  
  <pre><ccid_code> )u{bbjEJ  
public class WrapperInteger extends Wrapper { 56a-7 OG  
  private Integer value; T6 qTS`.  
K=+Axa!.  
  public WrapperInteger(Integer value) { s2.@zr5A  
    this.value=value; LYka.JV  
{=RA}}J  
  } V.m.c@  
  public WrapperInteger(int value){ <%)I@:  
1}@I+q  
    this.value=new Integer(value); Z}9<~)_i3  
  } & LL)-  
  public WrapperInteger(String value){ 3KO9Cn  
Ve!D  
    this.value=new Integer(value); |F%J"2'  
  } c;'S8  
N@p95  
  public String action(Visitor visitor){ j' vkr_Gd_  
    return( visitor.visit(this)); KHupXF-0  
  } 9$GS_j  
  public String toString(){ U,2em   
    if(value==null){ nYFSWF,  
        return "null"; Dsx^4,Ej  
    } -iLrd Q  
    return value.toString(); /! _88Wz&  
  } !$<`J]j#U#  
} /$!&gi^h  
o3(`| Ljf  
</ccid_code></pre> sF\&;rr%  
  </td> orhaZ8;,(  
</tr> `LpnKe+ }  
</table> %+[NdTg^,  
</ccid_nobr></CENTER> *2fMpg  
q\#Ha+<!\  
2y306rB+3I  
包装String类: eXlUG  
 6o^ fcM  
<CENTER><ccid_nobr> fhD7h??  
<table width="400" border="1" cellspacing="0" cellpadding="2" ' ,(:c  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> [ 7.mh0(  
<tr> C @*[N  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> #"ZWNCp  
  <pre><ccid_code> d"/&tMA=  
public class WrapperString extends Wrapper { i._x[N  
  private String wrapper; 2t%_%J  
  public WrapperString( String wrapper) { 3k^2b%q  
46uG[%j  
    this.wrapper = wrapper; *4md *JIge  
  } ]Wd{(b  
ww+y<(em{  
  public WrapperString( char[] wrap) { LFT{D L4;  
    wrapper = new String(wrap); zcg2rc%  
  } x<Ez0Zd  
9&_VO {t  
  public String action(Visitor visitor) { MP&C -R  
    return (visitor.vistit(this)); 8mJI F_!  
  } f*HUmSk`Yk  
PN :* o  
  public String toString() { NEVe}|MF-.  
    if(wrapper==null){ C5HSy,r!G  
        return "null"; w6U=Pr  
    } ~ |x&`Zt  
    return "'" + wrapper + "'"; 6k4w7PD7'#  
  } %]y!C#VX  
X|,2X%m  
} HT??##F!  
F1-)A[z  
</ccid_code></pre> *|AKHg|L  
  </td> R{Bx S`  
</tr> UD:ROfk<  
</table> CEE%orT7  
</ccid_nobr></CENTER> Zi.U{6E  
T {0R_>v'  
X=uuAvuW  
  具体访问者的实现: ^WQn98I  
.s M>Y(  
<CENTER><ccid_nobr> k#f(GfNI.  
<table width="400" border="1" cellspacing="0" cellpadding="2" ~0#]R230#  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> *u@  
<tr> [T+q{Jng+  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> A[ *lqx}  
  <pre><ccid_code> fn4O"67~-/  
public class Visitor { ?i\z(>  
  public Visitor() { `$ ?| wq6M  
  } `b1kH=g^  
C5pMVxIMq  
Gc"eB&E[O  
  public String vistit(WrapperString wrap){ 1N/R*G  
    return wrap.toString(); (ER +_I  
  } ch<b [y  
  public String visit(WrapperInteger value){ C16gy`f  
    return value.toString(); NNFl;^X  
  } /GaY^r<F.  
  public String visit(WrapperDate date){ i3f7Q%0px  
    return date.toString(); -7Q>eL   
  } Bn9; a  
} Be_e-dc\3r  
%|YcG$$}E  
</ccid_code></pre> yIZc#,o}  
  </td> 2 a1Ov@  
</tr> z!%uBoZk>  
</table> g>ws0'W#|  
</ccid_nobr></CENTER> X-6duzp%  
@Msz  
U WXq{B_  
  具体应用类的实现: (e Ui >x^  
x>gO5s  
<CENTER><ccid_nobr> ~4^o+qkX  
<table width="400" border="1" cellspacing="0" cellpadding="2" M\A&9Qc  
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> A]Bz|16G^,  
<tr> `{LrN"<h  
  <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> ?5enj)v  
  <pre><ccid_code> |(/#J "  
Gp%5P}`  
import java.util.*; #u3i.]lr="  
&X3U Y*p  
public class Test { #?~r) m|U  
l& 9xe+  
Y e  
  private Visitor visitor = new Visitor(); O!iv^ip  
(]tb EO(  
  public Test() { }75&HMLgb  
  } cH~nX^)r)  
Oxk NhD{q  
  public Visitor getVisitor() { /2%hIYG>aX  
    return visitor; 4ynL}bA  
  } }0>>3`F)  
y.{%7\>3w  
Slw!"P'p  
 Db X5+m  
Q[!.J"V  
  public int insertData(String tablename, List columNameCollection, s qUc!5  
                List values) { ZPW#)`>8<  
7#tW(bKo1h  
    StringBuffer query = new StringBuffer("insert into " + tablename + " ("); :u;8,o>-  
u'R>S^BU>  
    int count = 0; O/IK  
kak3$ESH  
    for (Iterator it = columNameCollection.iterator(); it.hasNext(); ) { gxWTc1)f  
        String columName = (String) it.next(); (Aw<*E^  
        query.append(columName); ;23NQjbS/  
        query.append(","); W6 c#l  
    } jgjcMrNm  
    query.deleteCharAt(query.length() - 1); z@Mt~RO/  
    query.append(") values("); !D8\%p]=n  
    for (Iterator it = values.iterator(); it.hasNext(); ) { &/~C~PK  
        Wrapper wrapper = (Wrapper) it.next(); @B;}H+6j7  
        String tmp = wrapper.action(getVisitor());  Ek b  
        query.append(tmp); %<zx(,xXZ  
        query.append(","); b4 8DS \  
    } E,oU( Z_  
    query.deleteCharAt(query.length() - 1); V&Bo{ O0  
    query.append(")"); uj %4a<f  
#GKA  
    System.out.println(query.toString()); 1@-C~x"pI  
    return count;  Y#z{lA  
  } b`7gPJ6  
cZ1FF4Y  
g'"pDD ,+|  
  public static void main(String[] args) { r LTwz?  
    Test test = new Test(); 1>llui-  
    String tableName = "cutomer"; KrW%3nZl9F  
    List columNameCollection = new ArrayList(); nt)W%'  
    String columName = "name"; A@1ak] X>  
    String columAge = "age"; xE\H$!/  
    String columFunctionTime="fuctiontime"; n {cF@z#?  
    columNameCollection.add(columName); Z6(,'oil"  
    columNameCollection.add(columAge); J4pA=8r33J  
    columNameCollection.add(columFunctionTime); >%|v(<>q  
    List values = new ArrayList(); U`FbFWYC  
    String name=null; oYl>xJuL  
    Wrapper wrapper1 = new WrapperString(name); X'9'`;JF  
    Wrapper wrapper2 = new WrapperInteger(1); 0_F<;j_  
    Wrapper wrapper3= new WrapperDate(new java.util.Date()); >6=r=;!Sm  
    values.add(wrapper1); u.sZJGf|  
    values.add(wrapper2); F/ X f;<o  
    values.add(wrapper3); pX3 YHuIh  
    test.insertData(tableName,columNameCollection,values); B8@X/lU  
  }  O~?liYx  
} NS&3=Kw<  
m'H%t>HH  
</ccid_code></pre> mk,YA-  
  </td> /9!vZIrT  
</tr>  Q1hp3J^  
</table> N9roo?,U  
</ccid_nobr></CENTER> "y#v1 @[X  
/)`B nld  
  程序打印结果: lV YE()h  
" G)T 3Y^  
insert into cutomer (name,age,fuctiontime) values(null,1,'Sat Aug 12 13:46:58 CST 2006') x[UED^B  
~J2O 5U"C  
这个输出是满足MSSQL执行插入的语法要求的.虽然这样就实现了想要的结果, ixs6SCj[%  
但是insertData(String tablename, List columNameCollection, List values) 方法在每次调 Z?nr},vng  
用的时候需要输入表名跟该表的列的集合,还是很麻烦,不尽人意,而且不同的数 Ie;9> n  
据库的表名是不一样的,因此最好用配置文件来解决这一个问题.

本贴标签:
顶端 Posted:2006-09-07 11:29 | [楼 主]
freelyflying




用户名: freelyflying
级别: 技术菜鸟
精华: 0
发帖: 9
经验值: 9 点
积分: 8 分
贡献值: 0
注册时间:2007-05-11



好難看懂哦。

顶端 Posted:2007-05-11 16:51 | 1 楼

 赛迪网技术社区 -> 数据库综合技术专区
快速发帖 顶端
内容
HTML 代码不可用

使用签名
Wind Code自动转换

字数检查 恢复数据
按 Ctrl+Enter 直接提交
表情 [更多]