自己动手写JDBC驱动来监视SQL语句(1)

Author 正正 Date  2011.01.26 21:30:00   转载请注明出处 正正博客 http://www.2009fly.com

其实这里主要是运用JDBC的工作原理,没有太大的技术含量,通过这篇文章介绍,希望能给你一些启迪及其加深你对JDBC工作机制的了解,同时也学习一下代理这种设计模式。注:写给初级入门者;如果您是这方面的专家,请您一笑而过!

首先要提到的是类java.sql.DriverManager,它是加载驱动的源泉。我们这里并不是自己去开发一个数据库的JDBC驱动,因此不 需要jni方面的知识。DriverManager,看名字就知道是对driver的管理,所有的driver需要先向它去注 册,DriverManager会将所有的driver的标识id,也就是driver的类名保存到它在内存中的“注册表中”,这里的注册表不是 windows系统里面的注册表,而只是一个容器或者说数据结构,大家可以跟踪调试查看到底是什么数据结构呢?

driver就是一个驱动程序,它的类的完全限定名称就是它的id,需要预先在DriverManager中进行注册。当我们 Class.forName() 显式地加载 JDBC 驱动程序时候,会在driver的static{…}静态方法中,调用DriverManager的静态方法 registerDriver(Driver driver)来注册自己。当然,如果注册表中已有自己的标识,则会忽略这次的注册。要知道,在 JDBC4.0中,驱动程序的名称需要配置到META-INF/services/java.sql.Driver 文件中,因此无须我们显示调用Class.forName()这个样板了,只是提醒一下。

先停下来,我们先写一下我们自己的Driver类,先暂时往下继续介绍其他的,以免忘记了刚刚说过的话。因为我们Driver只是一个 wrapper,也即是一个影子,并不做实际的工作,只是做一些装饰,真正的工作还是有真正的Driver来做。因此,我们的Driver叫做 MyDriver吧,它首先要实现java.sql.Driver接口,且需要包括一个真正的用于连接某一个数据库的jdbc驱动叫做 realDriver吧。因此在static{…}方法中,除了要注册我们自己的Driver外,还要注册真正的realDriver,但要保证我们的首 先注册,这样DriverManager会首先在“注册表”中发现我们,否则起不到我们需要的效果,别忘了,我们是要将sql语句打印成我们需要的格式, 我们也管这个叫“注入”吧,因为听着很酷!好了,假如我们的数据库是DBMaker(syscom的产品),首先要将其JDBC驱动jdbc30.jar 放到java.lib.classpath下:

package com.2009fly;

import … …//请自行添加

public class MyDriver implements Driver{

private Driver myDriver;

private Driver realDriver;//真正干活的driver

static{

myDriver=Class.forName(“com.2009fly.MyDriver”).newInstance();

DriverManager.registerDriver(myDriver);

realDriver=Class.forName(“dbmaker.sql.JdbcOdbcDriver”).newInstance();

DriverManager.registerDriver(realDriver);

}

…………

}

好了,下载我们的MyDriver和真正的realDriver已经全部注册到了DriverManager管理中心了,现在要开始干活了。首先, 我们都知道,要操作数据库,首先要获得一个连接Connection对象,而Connection是由Driver提供的,通过 getConnection()方法来提供。为了操作数据库,我们需要实现自己的Connection对象,当然了,干活的还需要真正的 Connection,因此我们的MyConnection里面要有一个真正的realConnection成员,由realConnection来完成 真正的活,而我们的MyConnection只要在realConnection之前完成一些自己的操作就OK了。

package com.2009fly;

import … …//请自行添加

public class MyConnection implements Connection{

private Connection realConnection;

public MyConnection(Connection conn){

realConnection=conn;

}

… …

}

刚才我们说了,Connection需要Driver来获取,那么我们现在要在我们的com.2009fly.MyDriver中添加getConnection()方法:

@Override

public Connection getConnection(String url,Properties info){

Connection conn = null;

if(realDriver.acceptsURL(url)){

conn = new MyConnection(realDriver.connect(url,info);

}else{

conn = null;

}

return conn;

}

从上面的代码看到,我们的Driver什么也没做,真正干活的是realDriver,看了吧,我们的只是个shell壳子或者说影子。现在得到了 Connection了,用同样的原来,我们构造自己的Statement和PreparedStatemen对象来实现我们的sql语句打印。提示:在 执行某条语句前,比如调用Statement对象的execute()方法时,可以像将执行的sql语句打印出来,这样就实现了我们的打印sql语句方法 了啊。同时,你也可以在加一个小小的功能,来记录每次执行sql语句的时间,这样子就可以来分析sql执行的效率,避免写低效率的sql语句。

呵呵… …今天就到这里了,如果你还有不明白的地方,可以email给我:zzcwfp@gmail.com.

———————————————————————————–------------------------

版权所有,欢迎转载,请在转载前注明出处:正正博客 http://www.2009fly.com

尊重别人的劳动成果也就是尊重自己!

推荐:2009FLY文摘|正正博客

———————————————————————————–-------------------------

posted @ 2011-01-28 11:52  zzc1986  阅读(635)  评论(0编辑  收藏  举报