JDBC 驱动
clickhouse-jdbc 使用最新的 Java 客户端实现了标准 JDBC 接口。
如果性能或直接访问至关重要,建议直接使用最新的 Java 客户端。
环境要求
- OpenJDK 8 或更高版本
设置
- Maven
- Gradle(Kotlin)
- Gradle
如果您在应用程序中使用 JDBC 驱动程序,且该应用程序需要将 jar 添加到 classpath,则需要从以下地址下载 jar 文件:
- Maven Central 并将其添加到 classpath 中
- 从版本
0.9.4开始,提供了构件 https://mvnrepository.com/artifact/com.clickhouse/clickhouse-jdbc-all - 使用限定符
all以获取包含所有打包(shaded)依赖的 jar。
- 从版本
- 或从官方仓库此处下载
配置
驱动程序类: com.clickhouse.jdbc.ClickHouseDriver
com.clickhouse.jdbc.ClickHouseDriver 是新旧 JDBC 实现的外观类,默认使用新的 JDBC 实现。
如需使用旧的 JDBC 实现,可在连接属性中将 clickhouse.jdbc.v1 属性设置为 true。
com.clickhouse.jdbc.Driver 是新版 JDBC 实现。
com.clickhouse.jdbc.DriverV1 是旧版 JDBC 实现。
URL 语法: jdbc:(ch|clickhouse)[:<protocol>]://endpoint[:port][/<database>][?param1=value1¶m2=value2][#tag1,tag2,...],例如:
jdbc:clickhouse:http://localhost:8123jdbc:clickhouse:https://localhost:8443?ssl=true
关于 URL 语法,有以下几点需要注意:
- URL 中 只能 指定一个 endpoint
- 当使用的协议不是默认的 'HTTP' 时,应显式指定 protocol。
- 如果端口不是默认的 '8123',则必须显式指定。
- 驱动程序不会根据端口推断协议,因此必须显式指定协议
- 如果已指定协议,则无需设置
ssl参数。
连接属性
主要配置参数在 java client 中定义。这些参数应按原样传递给驱动程序。驱动程序还有一些自有属性,它们不属于客户端配置的一部分,具体列举如下。
驱动属性:
| 属性 | 默认值 | 描述 |
|---|---|---|
disable_frameworks_detection | true | 禁用基于 User-Agent 的框架识别 |
jdbc_ignore_unsupported_values | false | 在不影响驱动工作的情况下抑制 SQLFeatureNotSupportedException 异常 |
clickhouse.jdbc.v1 | false | 使用旧版 JDBC 实现,而不是新版实现 |
default_query_settings | null | 允许在执行查询时传递默认查询设置 |
jdbc_resultset_auto_close | true | 在关闭 Statement 时自动关闭 ResultSet |
beta.row_binary_for_simple_insert | false | 使用基于 RowBinary writer 的 PreparedStatement 实现,仅适用于 INSERT INTO ... VALUES 形式的查询。 |
jdbc_resultset_auto_close | true | 在关闭 Statement 时自动关闭 ResultSet |
jdbc_use_max_result_rows | false | 启用该选项后,将使用服务器属性 max_result_rows 来限制查询返回的行数。启用时会覆盖用户设置的溢出模式。详细信息请参见 JavaDoc。 |
jdbc_sql_parser | JAVACC | 配置要使用的 SQL 解析器类型。可选值:ANTLR4、ANTLR4_PARAMS_PARSER、JAVACC。 |
配置示例:
这等同于以下 JDBC URL:
注意:无需对 JDBC URL 或属性进行 URL 编码,系统将自动进行编码。
客户端标识
有两种方式可以标识发起请求的应用程序:通过连接属性设置 com.clickhouse.client.api.ClientConfigProperties#CLIENT_NAME,或使用 java.sql.Connection#setClientInfo(String name, String value) 方法。
两种方式都会在查询日志中生成以下 http_user_agent 值:
操作标识
JDBC 驱动程序会为每个操作生成 query_id(目前该信息包含在服务器异常中)。
要为某个操作设置 log_comment,请使用 com.clickhouse.jdbc.StatementImpl#getLocalSettings 方法。这需要先将 Statement 或 PreparedStatement 强制转换为 com.clickhouse.jdbc.StatementImpl。
注意: 此方法适用于语句的单线程使用场景,因为 localSettings 在线程间是共享的。
支持的数据类型
JDBC 驱动支持与底层 Java 客户端相同的数据格式。
JDBC 类型映射
以下映射适用于:
ResultSet#getObject(columnIndex)方法将返回对应 Java 类的对象(Int8->java.lang.Byte,Int16->java.lang.Short等)。ResultSetMetaData#getColumnType(columnIndex)方法会返回相应的 JDBC 类型(Int8->java.lang.Byte,Int16->java.lang.Short等)。
有几种方法可以更改映射:
ResultSet#getObject(columnIndex, class)- 该方法会尝试将值转换为指定的class类型。此类转换存在一定限制。具体请参阅各节说明。
数值类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| Int8 | TINYINT | java.lang.Byte |
| Int16 | SMALLINT | java.lang.Short |
| Int32 | INTEGER | java.lang.Integer |
| Int64 | BIGINT | java.lang.Long |
| Int128 | OTHER | java.math.BigInteger |
| Int256 | OTHER | java.math.BigInteger |
| UInt8 | OTHER | java.lang.Short |
| UInt16 | OTHER | java.lang.Integer |
| UInt32 | OTHER | java.lang.Long |
| UInt64 | OTHER | java.math.BigInteger |
| UInt128 | OTHER | java.math.BigInteger |
| UInt256 | OTHER | java.math.BigInteger |
| Float32 | REAL | java.lang.Float |
| Float64 | DOUBLE | java.lang.Double |
| Decimal32 | DECIMAL | java.math.BigDecimal |
| Decimal64 | DECIMAL | java.math.BigDecimal |
| Decimal128 | DECIMAL | java.math.BigDecimal |
| Decimal256 | DECIMAL | java.math.BigDecimal |
| Bool | BOOLEAN | java.lang.Boolean |
- 数值类型之间可以相互转换。因此,可以将
Int8读取为Float64,反之亦然:rs.getObject(1, Float64.class)将返回Int8列的Float64值。rs.getLong(1)将返回Int8列的Long值。- 如果值在
Byte的取值范围内,rs.getByte(1)可以返回Int16列的Byte值。
- 由于存在数据损坏风险,不建议将更宽类型转换为更窄类型。
Bool类型也可以作为数值使用。- 所有数值类型都可以读取为
java.lang.String。
字符串类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| String | VARCHAR | java.lang.String |
| FixedString | VARCHAR | java.lang.String |
String只能被读取为java.lang.String或byte[]类型。FixedString读取时按原样返回,并在末尾用零字节补齐至该列的长度。(例如,将'John'定义为FixedString(10)时,读取结果为'John\0\0\0\0\0\0\0\0\0'。)
枚举类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| Enum8 | OTHER | java.lang.String |
| Enum16 | OTHER | java.lang.String |
Enum8和Enum16默认会映射到java.lang.String类型。- 枚举值可以通过相应的数值类型专用 getter 方法,或使用
getObject(columnIndex, Integer.class)方法读取为数值类型。 Enum16在内部映射为short类型,而Enum8映射为byte类型。应避免将Enum16以byte形式读取,否则存在数据损坏风险。- 可以在
PreparedStatement中将枚举值设置为字符串或数值。
日期/时间类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| Date | DATE | java.sql.Date |
| Date32 | DATE | java.sql.Date |
| DateTime | TIMESTAMP | java.sql.Timestamp |
| DateTime64 | TIMESTAMP | java.sql.Timestamp |
| Time | TIME | java.sql.Time |
| Time64 | TIME | java.sql.Time |
- 日期/时间类型会映射为
java.sql类型,以便与 JDBC 有更好的兼容性。不过,仍然可以通过ResultSet#getObject(columnIndex, Class<T>)方法,并将相应的类作为第二个参数传入,来获取java.time.LocalDate、java.time.LocalDateTime、java.time.LocalTime。rs.getObject(1, java.time.LocalDate.class)将把Date列的值以java.time.LocalDate的形式返回。rs.getObject(1, java.time.LocalDateTime.class)将把DateTime列的值以java.time.LocalDateTime的形式返回。rs.getObject(1, java.time.LocalTime.class)将把Time列的值以java.time.LocalTime的形式返回。
Date,Date32,Time,Time64不受服务器时区的影响。DateTime、DateTime64会受到服务器时区或会话时区的影响。DateTime和DateTime64可以通过getObject(colIndex, ZonedDateTime.class)获取为ZonedDateTime对象。
嵌套类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| Array | ARRAY | java.sql.Array |
| Tuple | OTHER | com.clickhouse.data.Tuple |
| Map | JAVA_OBJECT | java.util.Map |
| Nested | ARRAY | java.sql.Array |
Array默认会映射为java.sql.Array,以保证与 JDBC 的兼容性。这样也能提供更多关于返回数组值的信息,有助于进行类型推断。Array实现了getResultSet()方法,该方法返回一个与原始数组内容相同的java.sql.ResultSet。- 集合类型不应被读取为
java.lang.String,因为这并不是一种有效的数据表示方式(例如数组中的字符串值不会被加上引号)。 Map映射为JAVA_OBJECT,因为其值只能通过getObject(columnIndex, Class<T>)方法读取。Map不是java.sql.Struct,因为它没有具名列。
Tuple映射为Object[],因为它可以包含不同类型的元素,不能使用List来表示。Tuple可以通过getObject(columnIndex, Array.class)方法读取为Array类型。在这种情况下,Array#baseTypeName将返回Tuple列的定义。
写入数组
使用 java.sql.Connection#createArrayOf 来实例化 java.sql.Array 对象。该对象旨在统一不同数据库中的数组处理方式。
需要通过 Connection 将配置传递给 Array 的工厂方法。
该方法接受两个参数:
typeName- 数组元素的类型名称。例如Array(Int32)->"Int32"。elements- 数组中的实际元素。例如[[1, 2, 3], [4, 5, 6]]->new Integer[][] {{1, 2, 3}, {4, 5, 6}}。
Tuple 可以表示为 Object[] 或 java.sql.Struct(请参阅下文中关于如何写入 Tuple 的说明)。
示例
读取数组
使用 ResultSet#getArray(columnIndex) 读取 Array 对象。该对象可用于访问任意嵌套深度的数组。
Array#getResultSet() 方法可以以更统一的方式将数组元素读取为 java.sql.ResultSet,在数组元素的确切类型未知时尤为有用。
示例
写入 Tuple 类型
Tuple 类型会映射为 com.clickhouse.data.Tuple 对象,应通过调用 setObject(columnIndex, tuple) 方法将其作为该对象写入。
也可以使用 java.sql.Struct 对象来写入 Tuple,以获得更好的可移植性。
示例
读取 Tuple 类型
方法 getObject(columnIndex) 会返回 Object[]。通过调用 getObject(columnIndex, Array.class) 方法,可以将 Tuple 读取为 java.sql.Array。
示例
写入 Map 类型
只能将 Map 写入为 java.collections.Map 对象,因为该类型需要键值对(java.sql.Struct 不支持键值对)。
示例
读取 Map 类型
可以通过 getObject(columnIndex, Map.class) 方法将 Map 读取为 java.collections.Map 对象。
示例
写入嵌套类型
使用 java.sql.Connection#createStruct 来实例化 java.sql.Struct 对象。该对象旨在在不同数据库之间统一嵌套数据的处理。
需要通过 Connection 将配置信息传递给 Struct 的工厂方法。
该方法接受两个参数:
typeName- 嵌套元素类型的名称。例如Nested(Tuple(Int32, String))->"Nested(Tuple(Int32, String))"。elements- 嵌套结构中的实际元素。例如[1, 'test']->new Object[] {1, 'test'}.
示例
读取嵌套类型
使用 ResultSet#getStruct(columnIndex, StructDescriptor) 来读取 Nested 对象。该对象可用于访问任意嵌套深度的嵌套结构。
可以使用 Struct#getResultSet() 方法,以类似 java.sql.ResultSet 的、更加统一的方式读取嵌套元素。当嵌套元素的确切类型未知时,这非常有用。
示例
地理类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| Point | OTHER | double[] |
| Ring | OTHER | double[][] |
| Polygon | OTHER | double[][][] |
| MultiPolygon | OTHER | double[][][][] |
Nullable 和 LowCardinality 类型
Nullable和LowCardinality是用于封装其他类型的特殊类型。Nullable会影响ResultSetMetaData中类型名称的返回方式
特殊类型
| ClickHouse 类型 | JDBC 类型 | Java 类 |
|---|---|---|
| UUID | OTHER | java.util.UUID |
| IPv4 | OTHER | java.net.Inet4Address |
| IPv6 | OTHER | java.net.Inet6Address |
| JSON | OTHER | java.lang.String |
| AggregateFunction | OTHER | (二进制表示) |
| SimpleAggregateFunction | (封装类型) | (封装类) |
UUID不是 JDBC 标准中的类型,但它是 JDK 的一部分。默认情况下,通过调用getObject()方法会返回一个java.util.UUID实例。- 可以使用
getObject(columnIndex, String.class)方法将UUID作为String类型进行读写。 IPv4和IPv6不是 JDBC 标准类型,但它们是 JDK 的一部分。默认情况下,调用getObject()方法时会返回java.net.Inet4Address和java.net.Inet6Address实例。- 可以通过
getObject(columnIndex, String.class)方法将IPv4和IPv6读取/写入为String。
处理日期、时间和时区
请阅读 日期/时间指南,其中说明了驱动程序在处理 Date/Time 和 Timestamp 时的常见问题及相关逻辑。
创建连接
提供凭据和设置
简单语句
插入
HikariCP
更多信息
如需了解更多信息,请参阅我们的 GitHub 仓库 和 Java 客户端文档。
故障排除
日志
该驱动使用 slf4j 进行日志记录,并将使用 classpath 中首个可用的实现。
解决大批量插入时的 JDBC 超时问题
在 ClickHouse 中执行耗时较长的大批量插入操作时,可能会遇到如下 JDBC 超时错误:
这些错误可能会中断数据插入过程并影响系统稳定性。为解决该问题,可能需要在客户端操作系统中调整若干超时设置。
Mac OS
在 macOS 上,可以调整以下设置以解决此问题:
net.inet.tcp.keepidle: 60000net.inet.tcp.keepintvl: 45000net.inet.tcp.keepinit: 45000net.inet.tcp.keepcnt: 8net.inet.tcp.always_keepalive: 1
Linux
在 Linux 上,仅配置等效设置可能无法解决问题。由于 Linux 处理套接字 keep-alive 设置的方式不同,需要执行额外的步骤。请按照以下步骤操作:
- 在
/etc/sysctl.conf或其他相关配置文件中,调整以下 Linux 内核参数:
net.inet.tcp.keepidle: 60000net.inet.tcp.keepintvl: 45000net.inet.tcp.keepinit: 45000net.inet.tcp.keepcnt: 8net.inet.tcp.always_keepalive: 1net.ipv4.tcp_keepalive_intvl: 75net.ipv4.tcp_keepalive_probes: 9net.ipv4.tcp_keepalive_time: 60(可以考虑将该值从默认的 300 秒下调到更低的值)
- 修改内核参数后,运行以下命令以使更改生效:
设置这些配置后,您需要确保客户端在套接字上启用 Keep-Alive 选项:
迁移指南
主要变更
| 功能 | V1(旧版) | V2(新版) |
|---|---|---|
| 事务支持 | 部分支持 | 不支持 |
| 响应中的列重命名 | 部分支持 | 不支持 |
| 多语句 SQL | 不支持 | 不允许 |
| 命名参数 | 支持 | 不支持(JDBC 规范未定义) |
基于 PreparedStatement 的流式数据写入 | 支持 | 不支持 |
- JDBC V2 采用更轻量级的实现,因此移除了部分功能。
- JDBC V2 不支持流式数据传输,因为该功能既不在 JDBC 规范中定义,也未在 Java 标准中定义。
- JDBC V2 需要显式配置,不提供任何故障转移的默认配置。
- 协议应在 URL 中显式指定,不要基于端口号隐式推断协议。
配置更改
仅有两个枚举:
com.clickhouse.jdbc.DriverProperties- 驱动程序自身的配置属性。com.clickhouse.client.api.ClientConfigProperties- 客户端配置属性。客户端配置 变更详见 Java Client 文档。
连接属性按以下方式解析:
- 会优先从 URL 中解析属性,这些属性会覆盖所有其他属性。
- 驱动属性不会传递给客户端。
- 从 URL 中解析出端点(主机、端口和协议)。
示例:
数据类型变更
数值类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| Int8 | ✅ | TINYINT | java.lang.Byte | TINYINT | java.lang.Byte |
| Int16 | ✅ | SMALLINT | java.lang.Short | SMALLINT | java.lang.Short |
| Int32 | ✅ | INTEGER | java.lang.Integer | INTEGER | java.lang.Integer |
| Int64 | ✅ | BIGINT | java.lang.Long | BIGINT | java.lang.Long |
| Int128 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| Int256 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| UInt8 | ❌ | OTHER | java.lang.Short | OTHER | com.clickhouse.data.value.UnsignedByte |
| UInt16 | ❌ | OTHER | java.lang.Integer | OTHER | com.clickhouse.data.value.UnsignedShort |
| UInt32 | ❌ | OTHER | java.lang.Long | OTHER | com.clickhouse.data.value.UnsignedInteger |
| UInt64 | ❌ | OTHER | java.math.BigInteger | OTHER | com.clickhouse.data.value.UnsignedLong |
| UInt128 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| UInt256 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| Float32 | ✅ | REAL | java.lang.Float | REAL | java.lang.Float |
| Float64 | ✅ | DOUBLE | java.lang.Double | DOUBLE | java.lang.Double |
| Decimal32 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal64 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal128 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal256 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Bool | ✅ | BOOLEAN | java.lang.Boolean | BOOLEAN | java.lang.Boolean |
- 最大的区别在于,将无符号类型映射为 Java 类型,以提高可移植性。
字符串类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| String | ✅ | VARCHAR | java.lang.String | VARCHAR | java.lang.String |
| FixedString | ✅ | VARCHAR | java.lang.String | VARCHAR | java.lang.String |
FixedString在两个版本中均按原样读取。例如,对于'John',FixedString(10)会被读取为'John\0\0\0\0\0\0\0\0\0'。- 当使用
PreparedStatement#setBytes时,其值会被转换为unhex('<hex_string>'),然后再按String类型读取。 - 字符串以 UTF-8 编码存储。
日期/时间类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| Date | ❌ | DATE | java.sql.Date | DATE | java.time.LocalDate |
| Date32 | ❌ | DATE | java.sql.Date | DATE | java.time.LocalDate |
| DateTime | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP | java.time.OffsetDateTime |
| DateTime64 | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP | java.time.OffsetDateTime |
| Time | ✅ | TIME | java.sql.Time | 新类型/不支持 | 新类型/不支持 |
| Time64 | ✅ | TIME | java.sql.Time | 新类型/不支持 | 新类型/不支持 |
- 在 V2 中,
Time和Time64仅作为新增类型提供支持。 DateTime和DateTime64映射到java.sql.Timestamp类型,以提高与 JDBC 的兼容性。
枚举类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| Enum | ✅ | VARCHAR | java.lang.String | OTHER | java.lang.String |
| Enum8 | ✅ | VARCHAR | java.lang.String | OTHER | java.lang.String |
| Enum16 | ✅ | VARCHAR | java.lang.String | OTHER | java.lang.String |
嵌套类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| Array | ❌ | ARRAY | java.sql.Array | ARRAY | Object[] 或原始类型数组 |
| Tuple | ❌ | OTHER | Object[] | STRUCT | java.sql.Struct |
| Map | ❌ | JAVA_OBJECT | java.util.Map | STRUCT | java.util.Map |
| Nested | ❌ | ARRAY | java.sql.Array | STRUCT | java.sql.Struct |
- 在 V2 中,
Array默认会映射为java.sql.Array,以保证与 JDBC 的兼容性。这样做也能提供更多有关返回数组值的信息,有助于进行类型推断。 - 在 V2 中,
Array实现了getResultSet()方法,用于返回与原始数组内容相同的java.sql.ResultSet。 - V1 对
Map使用STRUCT,但始终返回java.util.Map对象。V2 通过将Map映射为JAVA_OBJECT解决了这一问题。 - V1 使用
STRUCT表示Tuple,但始终返回List<Object>对象。V2 将Tuple映射为OTHER,并默认返回Object[]。 - V2 引入了用于写入 Tuple 的
com.clickhouse.data.Tuple#Tuple。这有助于更容易判断某个值是 Tuple 还是数组。 PreparedStatement#setBytes和ResultSet#getBytes不适用于集合类型。这些方法专门用于处理二进制字符串(字节数据)。- 通常使用
java.sql.Array来写入和读取 Array 类型。JDBC 驱动对此提供了完整支持。 - 在 V2 中,
Nested被映射为Array,并将其表示为元组数组。 - V2 对
java.sql.Struct提供了部分支持,因为它与 Array 类型非常相似,但本身不支持键值对。Struct可用于写入Tuple类型的值。
地理类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| Point | ✅ | OTHER | double[] | OTHER | double[] |
| Ring | ✅ | OTHER | double[][] | OTHER | double[][] |
| Polygon | ✅ | OTHER | double[][][] | OTHER | double[][][] |
| MultiPolygon | ✅ | OTHER | double[][][][] | OTHER | double[][][][] |
Nullable 和 LowCardinality 类型
Nullable和LowCardinality是封装其他类型的特殊数据类型。- 在 V2 中,这些类型保持不变。
特殊类型
| ClickHouse 类型 | 与 V1 兼容 | JDBC 类型(V2) | Java 类(V2) | JDBC 类型(V1) | Java 类(V1) |
|---|---|---|---|---|---|
| JSON | ❌ | OTHER | java.lang.String | 不支持 | 不支持 |
| AggregateFunction | ✅ | OTHER | (二进制表示) | OTHER | (二进制表示) |
| SimpleAggregateFunction | ✅ | (封装类型) | (封装类) | (封装类型) | (封装类) |
| UUID | ✅ | OTHER | java.util.UUID | VARCHAR | java.util.UUID |
| IPv4 | ✅ | OTHER | java.net.Inet4Address | VARCHAR | java.net.Inet4Address |
| IPv6 | ✅ | OTHER | java.net.Inet6Address | VARCHAR | java.net.Inet6Address |
| Dynamic | ❌ | OTHER | java.Object | 不支持 | 不支持 |
| Variant | ❌ | OTHER | java.Object | 不支持 | 不支持 |
- V1 使用
VARCHAR作为UUID的 JDBC 类型,但始终返回java.util.UUID对象。V2 通过将UUID映射为 JDBC 类型OTHER,并同样返回java.util.UUID对象来修复此问题。 - V1 对
IPv4和IPv6使用VARCHAR,但始终返回java.net.Inet4Address和java.net.Inet6Address对象。V2 通过将IPv4和IPv6映射为 JDBC 类型OTHER来修复这一问题,并返回java.net.Inet4Address和java.net.Inet6Address对象。 Dynamic和Variant是 V2 中引入的新类型,在 V1 中不受支持。JSON基于Dynamic类型,因此仅在 V2 中受支持。- 可以通过
getBytes(columnIndex)方法将 IPv4 和 IPv6 的值读取为byte[]。不过,建议针对这些类型使用专门的类。 - V2 不支持将 IP 地址读取为数值类型,因为更适合在 InetAddress 类中执行该转换。
数据库元数据变更
- V2 中仅使用术语
Schema来指代数据库,将术语Catalog预留用于今后使用。 - V2 对
DatabaseMetaData.supportsTransactions()和DatabaseMetaData.supportsSavepoints()返回false。这一行为将在后续开发中进行调整。