java实战调用数据库_访问者模式实战:构建通用的数据库插入操作

在做一些简单的JDBC的API应用时,就老想只用一个方法向数据库不同的表做插入操作,省得

用一大堆的insert语句。访问者模式可以实现对未知的类进行操作,于是就用了这个简化了的模

式的实现方案。请高手指正。 在使用访问者模式之前先叙述一点概念性的东西。

静态类型的概念:变量被申明时的类型。实际类型:变量的实际类型。

比如 Object object=new String(); object静态类型是Object,实际类型是String.

观察者模式是一个比较难理解的模式,在理解观察者模式之前当然应该先理解双重分派的概念。

java语言支持静态的多分派跟动态的单分派。java通重载支持静态的多分派。书上的例子:

public class Mozi {

public void ride(Horse h){

System.out.println("ridding a horse");

}

public void ride(WhiteHorse w){

System.out.println("ridding a white horse");

}

public void ride(BlackHorse b){

System.out.println("rdding a black horse");

}

public static void main(String[] args){

Mozi mozi=new Mozi();

Horse w=new WhiteHorse();

Horse b=new BlackHorse();

mozi.ride(w);

mozi.ride(b);

}

}

程序打印输出:

ridding a horse

ridding a horse

原因就是对两次ride方法的调用传入的参量不同,但是它们的静态类型是一样的,都是 Horse;

这个过程在编译时期就完成了。

java通过方法置换支持动态分派。比如 String s1="ab"; Object o=s1+"c"; String s="abc";

o.equals(s) 打印true  o.equals()方法执行的是String类的equals()方法.java调用对象的

真实类型的方法,这就是动态分派。

双重分派:

public abstract class Vistor{

protected void processStrig(Object e){

if(e instanceof String){

String tmp=(String) e;

String need="'"+e+"'";

System.out.println(nedd);

}else if(e instanceof Integer){

String need=e.toString();

System.out.println(need);

}else if(e instanceof Date){

Date tmp=(Date) e;

String need="'"+tmp.toString()+"'";

}

....

}

}

public class ConcreteVisitor extends Visitor{

protected void processString(Object e){

super.processString(e);

}

}

方法的调用Visitor v=new ConcreteVisitor(); v.processString(new String("tt"));

v.processString()方法在调用的时候会检察v的真实类型,调用真实类型的方法,这个时候就

发生了一动态的单分派过程.当子类调用超类的方法的时候明显的根据instanceof判断的真实类

型去执行不同的方法,又发生了一次动态分派的过程.这个就是双重分派的实现。这种方法实现的

程序比较冗长和容易出错.

“返传球”方案:

public abstract class Vistor{

public abstract String processStrig(Object e);

}

public class ConcreteVisitor extends Visitor{

public String processString(WrapperString e){

String tmp= t.toString();

System.out.println(tmp);

}

public String processInteger(WrapperInteger e){

String tmp=e.toString();

System.out.println(tmp);

}

}

public class abstract Wrapper{

public abstract String processString(Vistor v);

}

public class WrapperString extends Wrapper{

public String processString(Vistor v){

v.processString(this);

}

public String toString(){

...

}

}

public class WrapperInteger extends Wrapper{

public String processInteger(Visitor v){

v.processString(this);

}

public String toString(){

...

}

}

方法的调用:

Visitor v = new ConcreteVisitor();

Wrapper wrapper= new WrapperString();

wrapper.processString(v);

当wrapper.processString()方法执行的时候会检察wrapper的真实类型,这个就产生了一次

动态单分派,processString()里面的语句v.processString()在执行的时候也会检察v的真

实类型,动态双重分派就发生了。

访问者模式的核心就是“返传球“方案的双重分派。其示意性类图:(注:虚线箭头划错了)

8dd544e56acc140371181c7a635e0325.png

在一个方法内实现向不同的表插入不同数据的具体实现方案(简化了的):因为整个方案里只需

要一个访问者对象,因此使用简化了的访问者模式。因为java基本类型及对应的类是不变模式的

实现:因此包装一下这些基本类型和类并实现访问者模式需要的方法。

public abstract class Wrapper {

public Wrapper() {

}

public abstract String action(Visitor visitor);

}

包装Date类:

import java.util.Date;

public class WrapperDate extends Wrapper {

private Date date;

public WrapperDate(Date date) {

this.date=date;

}

public String action(Visitor visitor){

return( visitor.visit(this));

}

public String toString(){

if (date==null){

return "null";

}

return "'"+date.toString()+"'";

}

}

包装Integer类:

public class WrapperInteger extends Wrapper {

private Integer value;

public WrapperInteger(Integer value) {

this.value=value;

}

public WrapperInteger(int value){

this.value=new Integer(value);

}

public WrapperInteger(String value){

this.value=new Integer(value);

}

public String action(Visitor visitor){

return( visitor.visit(this));

}

public String toString(){

if(value==null){

return "null";

}

return value.toString();

}

}

包装String类:

public class WrapperString extends Wrapper {

private String wrapper;

public WrapperString( String wrapper) {

this.wrapper = wrapper;

}

public WrapperString( char[] wrap) {

wrapper = new String(wrap);

}

public String action(Visitor visitor) {

return (visitor.vistit(this));

}

public String toString() {

if(wrapper==null){

return "null";

}

return "'" + wrapper + "'";

}

}

具体访问者的实现:

public class Visitor {

public Visitor() {

}

public String vistit(WrapperString wrap){

return wrap.toString();

}

public String visit(WrapperInteger value){

return value.toString();

}

public String visit(WrapperDate date){

return date.toString();

}

}

具体应用类的实现:

import java.util.*;

public class Test {

private Visitor visitor = new Visitor();

public Test() {

}

public Visitor getVisitor() {

return visitor;

}

public int insertData(String tablename, List columNameCollection,

List values) {

StringBuffer query = new StringBuffer("insert into " + tablename + " (");

int count = 0;

for (Iterator it = columNameCollection.iterator(); it.hasNext(); ) {

String columName = (String) it.next();

query.append(columName);

query.append(",");

}

query.deleteCharAt(query.length() - 1);

query.append(") values(");

for (Iterator it = values.iterator(); it.hasNext(); ) {

Wrapper wrapper = (Wrapper) it.next();

String tmp = wrapper.action(getVisitor());

query.append(tmp);

query.append(",");

}

query.deleteCharAt(query.length() - 1);

query.append(")");

System.out.println(query.toString());

return count;

}

public static void main(String[] args) {

Test test = new Test();

String tableName = "cutomer";

List columNameCollection = new ArrayList();

String columName = "name";

String columAge = "age";

String columFunctionTime="fuctiontime";

columNameCollection.add(columName);

columNameCollection.add(columAge);

columNameCollection.add(columFunctionTime);

List values = new ArrayList();

String name=null;

Wrapper wrapper1 = new WrapperString(name);

Wrapper wrapper2 = new WrapperInteger(1);

Wrapper wrapper3= new WrapperDate(new java.util.Date());

values.add(wrapper1);

values.add(wrapper2);

values.add(wrapper3);

test.insertData(tableName,columNameCollection,values);

}

}

程序打印结果:

insert into cutomer (name,age,fuctiontime) values(null,1,'Sat Aug 12 13:46:58 CST 2006')

这个输出是满足MSSQL执行插入的语法要求的.虽然这样就实现了想要的结果,

但是insertData(String tablename, List columNameCollection, List values) 方法在每次调

用的时候需要输入表名跟该表的列的集合,还是很麻烦,不尽人意,而且不同的数

据库的表名是不一样的,因此最好用配置文件来解决这一个问题.

欢迎加入QQ群:30406099

posted on 2006-08-14 14:39 傻 瓜 阅读(2295) 评论(2)  编辑  收藏 所属分类: 杂项

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用AngularJs编写的简单 益智游戏(附源代码)  这是一个简单的 javascript 项目。这是一个拼图游戏,也包含一个填字游戏。这个游戏玩起来很棒。有两个不同的版本可以玩这个游戏。你也可以玩填字游戏。 关于游戏 这款游戏的玩法很简单。如上所述,它包含拼图和填字游戏。您可以通过移动图像来玩滑动拼图。您还可以选择要在滑动面板中拥有的列数和网格数。 另一个是填字游戏。在这里你只需要找到浏览器左侧提到的那些单词。 要运行此游戏,您需要在系统上安装浏览器。下载并在代码编辑器中打开此项目。然后有一个 index.html 文件可供您修改。在命令提示符中运行该文件,或者您可以直接运行索引文件。使用 Google Chrome 或 FireFox 可获得更好的用户体验。此外,这是一款多人游戏,双方玩家都是人类。 这个游戏包含很多 JavaScript 验证。这个游戏很有趣,如果你能用一点 CSS 修改它,那就更好了。 总的来说,这个项目使用了很多 javascript 和 javascript 库。如果你可以添加一些具有不同颜色选项的级别,那么你一定可以利用其库来提高你的 javascript 技能。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值