要实现自己的JDBC驱动,最重要的是实现以下几个接口:
- java.sql.Driver
- java.sql.Connection
- java.sql.Statement
- java.sql.ResultSet
这篇文章讲解了如何实现一个简单的jdbc驱动: http://www.javaworld.com/javaworld/jw-05-2002/jw-0517-jdbcdriver.html
但是一个成熟的jdbc驱动, 光实现以上4个接口是不够的。用户经常使用数据库的元数据(metadata)信息, 比如返回某个库中所有表的相关信息; 或者结果集(ResultSet)的元数据信息, 比如返回某结果集所有列的列名。靠以上4接口不能实现,所以还得实现一些java.sql.XXMetaData的接口,另外还有一些例如java.sql.DataSource, java.sql.Savepoint都是比较重要的。
1. cloudbase
对于所有jdbc实现来说, Driver接口最重要的方法就是connect().以下是cloudbase中CBDriver的connect()方法实现.
public Connection connect( String url, java.util.Properties info)
throws SQLException
{
if( !acceptsURL( url))
{
return null;
}
String[] connParams = parseUrl( url);
String host = connParams[0];
int port = Integer.parseInt( connParams[1]);
String user = "test";
String password = "test";
CBConnection conn = new CBConnection( host, port, user, password);
return conn;
}
客户端通过CBConnection建立一个socket连接到CBServer上去, 形成一个输入和一个输出流。
CBConnection( String server, int port, String user, String pass)
throws SQLException
{
try
{
socket = new Socket( server, port);
socket.setSoTimeout( 900);
InputStream inStream = socket.getInputStream( );
InputStreamReader inStreamReader = new InputStreamReader( inStream);
sockIn = new BufferedReader( inStreamReader);
sockOut = new PrintStream( socket.getOutputStream( ));
String payload = user + "\t" + pass;
sockOut.println( payload);
String dbMetaDataStr = sockIn.readLine( );
dbMetaData = new CBDBMetaData( this, dbMetaDataStr);
this.port = port;
this.user = user;
this.server = server;
cmdMap = new Hashtable<String,Callback>( );
srr = new ServerResponseReader( );
srr.start( );
}
...
}
客户端连接的时候首先把user和password写入到输入流中, 服务端CBServer验证后,会把数据库的元数据(DataBaseMetaData)信息发信给客户端, 见com.business.cloudbase.net.DBMetaData类, 它把数据库元数据放入到一个map中,通过StringBuiilder把这个map序列化写入到socket接收端。
下面说以两个例子说明cloudbase的jdbc驱动是怎么工作的:
(1) sql查询
(2) 获得当前库所有表的信息
JDBC中DataBaseMetaData.getTables()方法实现此接口, 返回ResultSet类型。此结果集包含以下几列:
- TABLE_CAT String => 表类别(可为
null
) - TABLE_SCHEM String => 表模式(可为
null
) - TABLE_NAME String => 表名称
- TABLE_TYPE String => 表类型。典型的类型是 "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM"。
- REMARKS String => 表的解释性注释
- TYPE_CAT String => 类型的类别(可为
null
) - TYPE_SCHEM String => 类型模式(可为
null
) - TYPE_NAME String => 类型名称(可为
null
) - SELF_REFERENCING_COL_NAME String => 有类型表的指定 "identifier" 列的名称(可为
null
) - REF_GENERATION String => 指定在 SELF_REFERENCING_COL_NAME 中创建值的方式。这些值为 "SYSTEM"、"USER" 和 "DERIVED"。(可能为
null
)
这是jdbc规定的。
2. hsqldb
hsqldb把数据库的元数据也存在hsqldb的表中, 这些表是系统表. 因此获取元数据,就是select系统表的数据.
Server端每接收到一个客户端的连接, 就建立一个线程和一个新的会话(Session).
3. derby
derby的服务器端实现在drba包里.