要实现自己的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( ); 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包里.