如何实现一个最简单JDBC驱动

1,296 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情


JDBC 回顾

JDBC(Java Database Connectivity),是一套接口标准。

JDBC接口(API) 包括两个层次:

  • 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果。
  • 面向数据库的`API:Java Driver API,供开发商开发数据库驱动程序用。

驱动功能和分类

驱动主要包括三个功能:

  1. 连接数据源
  2. 发送命令语句给数据库
  3. 获取并处理结果集

大致有四种JDBC Drivers,我在项目中开发的的驱动大致应被归类为第三种。

  1. Type-1 driver or JDBC-ODBC bridge driver
  2. Type-2 driver or Native-API driver
  3. Type-3 driver or Network Protocol driver
  4. Type-4 driver or Thin driver

JDBC driver.png

JDBC 驱动实现

至少需要实现的接口

java.sql.Driver
java.sql.Connection
java.sql.Statement
java.sql.ResultSet    

包结构:

image.png

实现上述的四个接口后(PrepareStatement并不是必须的)就可以完成以下的查询操作:

Connection conn = null;
Statement st = null;
ResultSet rs = null;
​
Class.forName("com.fanruan.myJDBC.driver.MyDriver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", info);
st = conn.createStatement();
rs = st.executeQuery("select * from `student`");
​
System.out.println("-----------");
System.out.println("执行查询语句");
while(rs.next()) {
    ...
}

上述方法的调用流程:

MyDriver-connect
MyConnection-createStatement
MyStatement-executeQuery
MyStatement-isClosed
MyResultSet-next

Driver

这行代码可能是每一个Java初学者都要犯嘀咕的地方,为什么将驱动类加载进来就已经注册了驱动。

Class.forName("com.fanruan.myJDBC.driver.MyDriver");

在静态代码块中加载驱动是约定俗成的操作,静态代码块会在类被加载的同时执行。

主要需要实现的代码:

public class MyDriver implements Driver {
​
    //依靠静态函数块注册驱动
    static{
        try {
            DriverManager.registerDriver(new MyDriver());
        } catch (Exception e) {
            throw new RuntimeException("Can't register driver");
        }
    }
​
    @Override
    public Connection connect(String url, Properties info) throws SQLException {
        MyConnection conn = new MyConnection(client);
        return (Connection) conn;
    }
}

Connection

public class MyConnection implements Connection {
​
     @Override
    public Statement createStatement() throws SQLException {
        ...
    }
​
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        ...
    }
    
    // 返回元数据信息,通过自己实现的 MyDatabaseMetaData
    @Override
    public DatabaseMetaData getMetaData() throws SQLException {
        ...
    }
}

MyDatabaseMetaData.java 主要是提供驱动的一些元信息

Statement

public class MyStatement implements Statement {
​
    @Override
    public ResultSet executeQuery(String sql) throws SQLException {
        ...
    }
    
     @Override
    public boolean isClosed() throws SQLException {
        ...
    }

ResultSet

public class MyResultSet implements ResultSet {
    
    @Override
    public boolean next() throws SQLException {
        ...
    }
    
    public XX getXX(){
        ...
    }

本文参考

[开发自己的JDBC驱动——基本说明]

csv JDBC driver

Java中JDBC的使用详解