Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

# 聊聊 Sharding-Jdbc 的简单原理初篇

发表于 2021-12-26 更新于 2022-06-11 分类于 Java 阅读次数： 阅读次数： Disqus：

在上一篇 sharding-jdbc 的介绍中其实碰到过一个问题，这里也引出了一个比较有意思的话题
就是我在执行 query 的时候犯过一个比较难发现的错误，

    ResultSet resultSet = ps.executeQuery(sql);

实际上应该是

    ResultSet resultSet = ps.executeQuery();

而这里的差别就是，是否传 sql 这个参数，首先我们要知道这个 ps 是什么，它也是个接口`java.sql.PreparedStatement`,而真正的实现类是`org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement`,我们来看下继承关系
这里可以看到继承关系里有`org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedOperationPreparedStatement`
那么在我上面的写错的代码里

    @Override
    public final ResultSet executeQuery(final String sql) throws SQLException {
        throw new SQLFeatureNotSupportedException("executeQuery with SQL for PreparedStatement");
    }

这个报错一开始让我有点懵，后来点进去了发现是这么个异常，但是我其实一开始是用的更新语句，以为更新不支持，因为平时使用没有深究过，以为是不是需要使用 Mybatis 才可以执行更新，但是理论上也不应该，再往上看原来这些异常是由 sharding-jdbc 包装的，也就是在上面说的`AbstractUnsupportedOperationPreparedStatement`，这其实也是一种设计思想，本身 jdbc 提供了一系列接口，由各家去支持，包括 mysql，sql server，oracle 等，而正因为这个设计，所以 sharding-jdbc 也可以在此基础上进行设计，我们可以总体地看下 sharding-jdbc 的实现基础
看了前面`ShardingSpherePreparedStatement`的继承关系，应该也能猜到这里的几个类都是实现了 jdbc 的基础接口，
在前一篇的 demo 中的

    Connection conn = dataSource.getConnection();

其实就获得了`org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection#ShardingSphereConnection`
然后获得`java.sql.PreparedStatement`

    PreparedStatement ps = conn.prepareStatement(sql)

就是获取了`org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement`
然后就是执行

    ResultSet resultSet = ps.executeQuery();

然后获得结果
`org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSet`

其实像 mybatis 也是基于这样去实现的