参数命名的重要性,记一次JDBC参数冲突

Properties info = new Properties();
                info.setProperty("user", "root");
                info.setProperty("password", "850656");
                info.setProperty("agentID", "1001");
                info.setProperty("dbName", "mysql");
                
                // 载入自定义的驱动
                Class.forName("com.fanruan.myJDBC.driver.MyDriver");
                Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", info);
                Statement st = conn.createStatement();
                ResultSet rs = st.executeQuery("select * from `student`");复制代码

如上,由于我重写了JDBC驱动,也就是上文的com.fanruan.myJDBC.driver.MyDriver。重写的效果大概是通过RPC调用客户端的JDBC执行相应操作。由于RPC调用的需要,在DriverManager.getConnection(String url, Properties info)中多封装了两个参数,agentIDdbName方便 Agent 对于收到的调用消息进行分发。测试运行时,在客户端显示如下:

Properties参数冲突.png

写的程序有bug我已经习惯了,但是令我费解的是,我明明在 url中指明了数据库为 test, 为何会报错说Table 'mysql.student' doesn't exist呢?

已知建立连接最终调用的是connect方法:

    public java.sql.Connection connect(String url, Properties info) throws SQLException {
        ...
    }
​
复制代码

mysql的JDBC实现中,会对传入的 Properties 参数进行解析

public ConnectionImpl(HostInfo hostInfo) throws SQLException {
    ...
        this.database = hostInfo.getDatabase();
    ...
复制代码
 public String getDatabase() {
     // 在 PropertyKey 中刚好有个叫 dbname 的键
        String database = this.hostProperties.get(PropertyKey.DBNAME.getKeyName());
        return isNullOrEmpty(database) ? "" : database;
    }
复制代码

dbname键.png

导致本来已经被解析为testdatabase

originDataBase.png

被覆盖成了mysql导致了上面所说的错误。

finaldatabase.png

可以看到进入getConnectionURLInstance时,dbName还是驼峰命名。

扫描二维码关注公众号,回复: 14441296 查看本文章

被处理为connectionURL之后就变成了dbname,这也是上面覆盖database的前置条件。

connectionURL.png

至于为什么,那是因为解析DBNAME的时候设置的是大小写不敏感:

dbname.png

猜你喜欢

转载自juejin.im/post/7127953601145602056