根据字符串,引入不通的 jdbc 驱动,为什么会错乱?

2021-09-07 22:00:15 +08:00
 among

   // 驱动
    public String GetDriver(String url) {
        try {
            if (url.startsWith("jdbc:as400")) {
                return "com.ibm.as400.access.AS400JDBCDriver";
            } else if (url.startsWith("jdbc:oracle")) {
                return "oracle.jdbc.driver.OracleDriver";
            } else if (url.startsWith("jdbc:mysql")) {
                return "com.mysql.cj.jdbc.Driver";
            } else if (url.startsWith("jdbc:sqlserver")) {
                return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
            } else if (url.startsWith("jdbc:informix-sqli")) {
                return "com.informix.jdbc.IfxDriver";
            } else if(url.startsWith("jdbc:sybase")) {
            	return "com.sybase.jdbc4.jdbc.SybDriver";
            }else if(url.startsWith("jdbc:db2")) {
            	return "com.ibm.db2.jcc.DB2Driver";
            }else if(url.startsWith("jdbc:dm")) {
                return "dm.jdbc.driver.DmDriver";
            }else {
                log.error("连接字符串有误:" + url);
                return "";
            }
        } catch (Exception e) {
            log.error("返回驱动异常:" + e);
            return "";
        }
    }

com.tp.util.DataBaseRun : 连接:jdbc:oracle:thin:@xx.xx.xx.xx:1521/db 异常:java.sql.SQLNonTransientConnectionException: Cannot load connection class because of underlying exception: com.mysql.cj.exceptions.WrongArgumentException: Malformed database URL, failed to parse the main URL sections.

在并发较多的情况下,会出现错乱的情况。

如 oracle 的,会到 mysql 的类中去寻找。

3066 次点击
所在节点    Java
25 条回复
selca
2021-09-08 14:44:40 +08:00
由于 SPI 机制,Class.forName 基本不会影响到下一行 DriverManager.getConnection 的调用,我跟 18 和 19 楼的观点一样,Java 的 getConnection 方法本身就是依次遍历所有注册驱动,如果成功后就直接返回,哪知道 mysql 的驱动只成功了一部分,既然有判断 url 类型的代码,就直接通过 url 去手动取得连接就行。
among
2021-09-08 14:46:54 +08:00
ikas
2021-09-08 15:08:55 +08:00
@among 这里基本说的基本就是上面那个..最好的方式,就是你自己先 getDriver
Driver 这个是可以缓存的..还有也没有必要每次 class.forname..
buster
2021-09-08 17:24:11 +08:00
又学到新的一招,从没遇到过类似的问题。
曾经做过的连多 DB 的事情,每种 DB 都会搞一个带线程池的工具类。
pjntt
2021-09-12 00:49:02 +08:00
调用这个方法时候是线程安全的吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/800497

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX