gpt4 book ai didi

java - 为什么 OJDBC 7 不将 CHAR 数据类型映射到 Java 字符串?

转载 作者:搜寻专家 更新时间:2023-11-01 00:55:07 25 4
gpt4 key购买 nike

OJDBC 的工作之一是将 Oracle 数据类型映射到 Java 类型。

但是,我们注意到,如果我们给 CHAR 数据类型,它不会映射到 java.lang.String。显示此行为的版本是:OJDBC7 v12.1.0.2OJDBC6 v12.1.0.1。旧版本确实将 CHAR 数据类型映射到:java.lang.String

深入挖掘,我们发现OJDBC的oracle.jdbc.driver包中有一个类:StructMetaData,实现了Oracle数据类型到Java类型的映射.其中有一个方法:'getColumnClassName(int arg0)'值得关注。我们注意到,对于 OJDBC v7,映射到 java.lang.String 的 case 如下:

    int arg1 = this.getColumnType(arg0);
switch (arg1) {
case -104:
return "oracle.sql.INTERVALDS";
case -103:
return "oracle.sql.INTERVALYM";
case -102:
return "oracle.sql.TIMESTAMPLTZ";
case -101:
return "oracle.sql.TIMESTAMPTZ";
case -15:
case -9:
case 12:
return "java.lang.String";
...

但是,在旧的 OJDBC 实现中,它看起来像这样:

    int arg1 = this.getColumnType(arg0);
switch (arg1) {
case -104:
return "oracle.sql.INTERVALDS";
case -103:
return "oracle.sql.INTERVALYM";
case -102:
return "oracle.sql.TIMESTAMPLTZ";
case -101:
return "oracle.sql.TIMESTAMPTZ";
case -15:
case -9:
case 1:
case 12:
return "java.lang.String";
...

在后一种情况下,还有一个映射到 java.lang.String 的情况,即。 '情况1'。此“案例 1”未映射到上面显示的第一个代码片段中的 java.lang.String

深入观察,这个“案例 1”被映射到同一 StructMetaData 类的 getColumnTypeName(int arg0 ) 方法中的 CHAR :

public String getColumnTypeName(int arg0) throws SQLException {
int arg1 = this.getColumnType(arg0);
int arg2 = this.getValidColumnIndex(arg0);
switch (arg1) {
case -104:
return "INTERVALDS";
case -103:
return "INTERVALYM";
case -102:
return "TIMESTAMP WITH LOCAL TIME ZONE";
case -101:
return "TIMESTAMP WITH TIME ZONE";
case -15:
return "NCHAR";
case -13:
return "BFILE";
case -9:
return "NVARCHAR";
case -2:
return "RAW";
case 1:
return "CHAR";
...

因此,如果我们使用 OJDBC 7 或 OJDBC6 v12.1.0.1 并指定 CHAR 作为列的数据类型,则以下代码返回 null对此列的索引的调用:

 for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
...
resultSetMetaData.getColumnClassName(columnIndex)
...

如果我替换旧版本的 OJDBC jar(例如:11.2.0.3),则返回相同的代码:java.lang.String。这是一个错误还是被设计删除了?有人遇到过同样的问题吗?

最佳答案

好收获...!

它看起来确实像一个错误;也许唯一反对的理由是,这将是 Oracle 的一个令人难以置信的巨大忽视。

专业错误:

  • 向后兼容性问题。 jdbc 驱动程序的更新会破坏明确依赖于 CHAR 声明
  • 的现有应用程序
  • 关于 JPublisher 的说明 Data Type and Java-to-Java Type Mappings描述了 12c 的映射

(注意第一行,与 CHAR 类型相关,它映射到 java.lang.String)

| SQL and PL/SQL Data Type | Oracle Mapping   | JDBC Mapping
|------------------------- |------------------|-----------------------------------------------
| CHAR, CHARACTER, LONG, | |
|STRING, VARCHAR, VARCHAR2 | oracle.sql.CHAR | java.lang.String
| NCHAR, NVARCHAR2 | oracle.sql.NCHAR | oracle.sql.NString
| NCLOB | oracle.sql.NCLOB | oracle.sql.NCLOB

针对错误:

  • 一个奇特的假设可能会争辩说 Oracle 正试图从支持的类型中消除 CHAR。事实上,CHAR 类型与 VARCHAR2 相比确实没有任何优势,而且一些缺点使其成为别无选择的选择。在过去,我喜欢这样一个事实,即“CHAR”向其他开发人员传达您打算定义一个具有预定义且始终固定长度的项目的意图,但它甚至没有强制执行(它只是填充字符串,如果你用太短的值填充它)。有兴趣的话,优秀的书中有一段Expert Oracle Database Architecture - Oracle Database 9i, 10g, and | Thomas Kyte | Apress致力于这个话题。您可以在 Ask Tom "Char Vs Varchar" 中阅读摘录, 在作者引用他自己的书的地方:

The fact that a CHAR/NCHAR is really nothing more than a VARCHAR2/NVARCHAR2 in disguise makes me of the opinion that there are really only two character string types to ever consider, namely VARCHAR2 and NVARCHAR2. I have never found a use for the CHAR type in any application. Since a CHAR type always blank pads the resulting string out to a fixed width, we discover rapidly that it consumes maximum storage both in the table segment and any index segments. That would be bad enough, but there is another important reason to avoid CHAR/NCHAR types: they create confusion in applications that need to retrieve this information (many cannot “find” their data after storing it). The reason for this relates to the rules of character string comparison and the strictness with which they are performed. ....

[然后在同一篇文章中有一个很好的例子;非常值得一读]

CHAR 不好的事实当然不能证明 Oracle 可以在没有明确通知的情况下破坏现有的应用程序;所以假设它是一个错误显然更明智。

鉴于理论上它不会有缺点,作为一种极端的解决方法,您可以更改所有涉及的表以将其 CHAR 类型重新定义为 VARCHAR2(如果您有权这样做,并且这是可行的)。

关于java - 为什么 OJDBC 7 不将 CHAR 数据类型映射到 Java 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37332907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com