Java JDBC连接字符串语法和剖析

Java JDBC连接字符串语法和剖析,java,jdbc,syntax,connection-string,Java,Jdbc,Syntax,Connection String,多年来,我使用JDBC连接到许多不同的关系系统:H2、HSQLDB、MySQL、Oracle、Postgres等。在每种情况下,每个系统似乎都有自己的连接字符串语法风格 我无法想象像JDBC这样的长期API不会有一个定义的、强制的连接字符串验证语法。例如: 一些有效的HSQLDB连接字符串: jdbc:hsqldb:mem:mymemdb jdbc:hsqldb:res:org.my.path.resdb jdbc:hsqldb:file:/opt/db/testdb MySQL: jdbc:

多年来,我使用JDBC连接到许多不同的关系系统:H2、HSQLDB、MySQL、Oracle、Postgres等。在每种情况下,每个系统似乎都有自己的连接字符串语法风格

我无法想象像JDBC这样的长期API不会有一个定义的、强制的连接字符串验证语法。例如:

一些有效的HSQLDB连接字符串:

jdbc:hsqldb:mem:mymemdb
jdbc:hsqldb:res:org.my.path.resdb
jdbc:hsqldb:file:/opt/db/testdb
MySQL:

jdbc:mysql://localhost/test
博士后:

jdbc:postgresql://localhost/test
H2:

从所有这些示例中,我收集了基本的通用语法:

jdbc:<vendor>:<vendor-specific-uri>
jdbc::
其中,
是系统的名称(
h2
mysql
等),而
是确定数据库位置的路径或特定于供应商的方法

我已经做了很多挖掘工作,就我的一生而言,我似乎找不到JDBC在哪里定义了有效的连接字符串语法。具体而言:

  • 有效JDBC连接字符串的一般语法/定义是什么
  • 连接字符串的每个令牌/组件的不同名称是什么?例如,“
    jdbc:
    ”是否被称为“jdbc协议”之类的东西?我的
    段的正确名称是什么

如果查看源代码,您将看到JDBC驱动程序实现了。这个接口有一个方法

boolean acceptsURL(String url) throws SQLException;
从JavaDoc:

检索驱动程序是否认为可以打开到给定URL的连接。通常,如果驱动程序理解URL中指定的子目录,则返回
true
;如果不理解,则返回
false

因此,数据库的dirver负责实现此方法。对于H2,这是

其他数据库管理系统有不同的实现


编辑:对于H2,常量
常量。开始URL
“jdbc:H2:”
。因此,即使是领先的
jdbc
也不是任何正式语法的一部分。

URL语法在中有规定,特别是在第9.4节:

JDBC URL的格式为:

jdbc:<subprotocol>:<subname>
jdbc::
其中
subtocol
定义了一个或多个驱动程序可能支持的数据库连接机制的类型。
子名称的内容和语法取决于
次级方案

注意–JDBC URL不需要完全遵循RFC 3986《统一资源标识符(URI):通用语法》中定义的URI语法

没有比这更正式的了。子程序通常是数据库或驱动程序的某种标识符。子名称是自由形式的,尽管驱动程序通常遵循类似URI的语法


也没有必要再拘泥于形式。
DriverManager
只需依次提供每个注册的
java.sql.Driver
的URL,第一个接受的用于连接。

谢谢@Lutz Horn(+1)-这实际上让我有点震惊。那么,基于
acceptsUrl(…)
的JavaDoc,可以安全地说JDBC连接字符串的形式语法/结构是:
JDBC:/:
?JDBC规范实际上指定了
JDBC::
,但是它不是在
DriverManager
本身中强制执行的。还要注意的是
DriverManager
实际上没有使用
acceptsURL
,它只会调用每个注册的驱动程序,第一个驱动程序不返回
null
,但返回
连接或抛出
SQLException
就是正确的驱动程序。
@Override
public boolean acceptsURL(String url) {
    if (url != null) {
        if (url.startsWith(Constants.START_URL)) {
            return true;
        } else if (url.equals(DEFAULT_URL)) {
            return DEFAULT_CONNECTION.get() != null;
        }
    }
    return false;
}
jdbc:<subprotocol>:<subname>