为什么现在不用再写 Class.forName("com.mysql.jdbc.Driver")?DriverManager 怎么在一堆驱动里选一个?驱动从别的类加载器加载会怎样?这篇用四个真实的嵌入式数据库驱动和一个自己写的驱动逐项验证。
h2-2.3.232.jar java.sql.Driver 服务文件: ['org.h2.Driver'] hsqldb-2.7.4.jar java.sql.Driver 服务文件: ['org.hsqldb.jdbc.JDBCDriver'] sqlite-jdbc-3.46.1.0.jar java.sql.Driver 服务文件: ['org.sqlite.JDBC'] derby-10.16.1.1.jar java.sql.Driver 服务文件: ['org.apache.derby.iapi.jdbc.AutoloadedDriver'] derbytools-10.16.1.1.jar java.sql.Driver 服务文件: (没有) derbyshared-10.16.1.1.jar java.sql.Driver 服务文件: (没有)
1 没有任何 Class.forName,第一次调用 DriverManager.getDrivers():耗时 20 ms,发现 4 个驱动:[org.h2.Driver, org.hsqldb.jdbc.JDBCDriver, org.sqlite.JDBC, org.apache.derby.iapi.jdbc.AutoloadedDriver]
jdbc:h2:mem:t → 驱动 org.h2.Driver;连接 H2 2.3.232 (2024-08-11);驱动版本 2.3;JDBC true
jdbc:hsqldb:mem:t → 驱动 org.hsqldb.jdbc.JDBCDriver;连接 HSQL Database Engine 2.7.4;驱动版本 2.7;JDBC true
jdbc:sqlite::memory: → 驱动 org.sqlite.JDBC;连接 SQLite 3.46.1;驱动版本 3.46;JDBC false
jdbc:derby:memory:t;create=true → 驱动 org.apache.derby.iapi.jdbc.AutoloadedDriver;连接 Apache Derby 10.16.1.1 - (1901046);驱动版本 10.16;JDBC true
jdbc:nonexistent:x → SQLException: No suitable driver (SQLState 08001)
mysql://nojdbc → SQLException: No suitable driver (SQLState 08001)
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. org.h2.Driver acceptsURL(jdbc:h2:mem:x)=true,acceptsURL(jdbc:sqlite::memory:)=false
org.hsqldb.jdbc.JDBCDriver acceptsURL(jdbc:h2:mem:x)=false,acceptsURL(jdbc:sqlite::memory:)=false
org.sqlite.JDBC acceptsURL(jdbc:h2:mem:x)=false,acceptsURL(jdbc:sqlite::memory:)=true
org.apache.derby.iapi.jdbc.AutoloadedDriver acceptsURL(jdbc:h2:mem:x)=false,acceptsURL(jdbc:sqlite::memory:)=false
DriverManager.getConnection("jdbc:sqlite::memory:")
trying org.h2.Driver
trying org.hsqldb.jdbc.JDBCDriver
trying org.sqlite.JDBC
getConnection returning org.sqlite.JDBC
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 2 deregisterDriver(h2) 之后 getConnection(jdbc:h2:mem:y):No suitable driver found for jdbc:h2:mem:y (SQLState 08001)
registerDriver 重新注册后:连接成功,H2
不经 DriverManager,直接 driver.connect:成功
driver.connect 遇到不认识的 URL 返回:null
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 3 用独立的 URLClassLoader 加载 org.h2.Driver:加载器 URLClassLoader;DriverManager 已注册的驱动(按名字)[]
DriverManager.getConnection:No suitable driver found for jdbc:h2:mem:l
同一个驱动类手动实例化后直接 connect:true [什么都不做]
已注册驱动 [org.h2.Driver];getConnection(jdbc:my:x):No suitable driver found for jdbc:my:x
[Class.forName("MyDriver")]
[MyDriver 的静态初始化块执行了:已 registerDriver]
已注册驱动 [MyDriver, org.h2.Driver];getConnection(jdbc:my:x) 成功,实际连接的是 H2
[-Djdbc.drivers=MyDriver]
[MyDriver 的静态初始化块执行了:已 registerDriver]
已注册驱动 [org.h2.Driver, MyDriver];getConnection(jdbc:my:x) 成功,实际连接的是 H2
[在 classpath 的 META-INF/services/java.sql.Driver 里登记 MyDriver]
[MyDriver 的静态初始化块执行了:已 registerDriver]
已注册驱动 [MyDriver, org.h2.Driver];getConnection(jdbc:my:x) 成功,实际连接的是 H2