自己动手写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
尊重别人的劳动成果也就是尊重自己!
———————————————————————————–-------------------------