Dol*_*ava 5 java oracle11g ojdbc
OJDBC的工作之一是将Oracle数据类型映射到Java类型.
但是,我们注意到,如果我们提供CHAR数据类型,则不会映射到java.lang.String.显示此行为的版本是:OJDBC7 v12.1.0.2和OJDBC6 v12.1.0.1.旧版本确实将CHAR数据类型映射到:java.lang.String.
在深入挖掘时,我们发现有一个类:StructMetaData在oracle.jdbc.driverOJDBC 的包中实现Oracle数据类型到Java类型映射.其中有一个方法:'getColumnClassName(int arg0)'值得关注.我们注意到,对于OJDBC v7,映射到的案例java.lang.String如下:
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";
...
Run Code Online (Sandbox Code Playgroud)
但是,在较旧的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";
...
Run Code Online (Sandbox Code Playgroud)
java.lang.String在后一种情况下,还有一个映射到的附加案例即.'情况1'.此"案例1"未映射到java.lang.String上面显示的第一个代码段中.
在更深入地看,这个'case 1'被映射到同一个类CHAR的getColumnTypeName(int arg0 )方法中StructMetaData:
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";
...
Run Code Online (Sandbox Code Playgroud)
因此,如果我们使用OJDBC 7或OJDBC6 v12.1.0.1并指定CHAR列的数据类型,则以下代码将null在此列的索引的调用时返回:
for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
...
resultSetMetaData.getColumnClassName(columnIndex)
...
Run Code Online (Sandbox Code Playgroud)
如果我替换旧版本的OJDBC jar(例如:11.2.0.3),则相同的代码返回:java.lang.String.这是一个错误还是被设计删除了?以前有人遇到过同样的问题吗?
接得好...!
\n\n它确实看起来像一个错误;也许唯一反对的理由是,这将是甲骨文的一个令人难以置信的巨大忽视。
\n\n专业错误:
\n\nCHAR声明的现有应用程序(注意第一行,与类型相关CHAR,映射到java.lang.String)
| SQL and PL/SQL Data Type | Oracle Mapping | JDBC Mapping\n|------------------------- |------------------|-----------------------------------------------\n| CHAR, CHARACTER, LONG, | | \n|STRING, VARCHAR, VARCHAR2 | oracle.sql.CHAR | java.lang.String\n| NCHAR, NVARCHAR2 | oracle.sql.NCHAR | oracle.sql.NString \n| NCLOB | oracle.sql.NCLOB | oracle.sql.NCLOB \nRun Code Online (Sandbox Code Playgroud)\n\n对抗错误:
\n\nCHARs 从受支持的类型中剔除。事实上,与 相比,该CHAR类型确实没有任何优势VARCHAR2,而且一些缺点使其成为别无选择。在过去,我喜欢这样一个事实:“ CHAR”向其他开发人员传达您定义具有预定义且始终固定长度的项目的意图,但它甚至不强制执行此操作(它只是填充字符串,如果您用\n如果您有兴趣,优秀的《专家 Oracle 数据库架构 - Oracle 数据库 9i、10g 和 |》一书中有一个部分。托马斯·凯特 | Apress致力于该主题。您可以阅读Ask Tom“Char Vs Varchar”中的摘录,其中作者引用了他自己的书:\n\n\nCHAR/NCHAR 实际上只不过是变相的 VARCHAR2/NVARCHAR2,这一事实使我认为实际上只有两种字符串类型需要考虑,即 VARCHAR2 和 NVARCHAR2。我从未在任何应用程序中发现 CHAR 类型的用途。由于 CHAR 类型总是将结果字符串空白填充到固定宽度,因此我们很快发现它在表段和任何索引段中消耗了最大的存储空间。这已经够糟糕的了,但是避免 CHAR/NCHAR 类型还有另一个重要原因:它们会在需要检索此信息的应用程序中造成混乱(许多应用程序在存储数据后无法 \xe2\x80\x9cfind\xe2\x80\x9d 数据) )。其原因与字符串比较的规则及其执行的严格性有关。....
\n
[然后在同一篇文章中给出了一个很好的例子;非常值得一读]
\n\n事实是CHAR并不能成为 Oracle 在没有明确通知的情况下破坏现有应用程序的理由;因此,它是一个错误的假设显然更合理。
鉴于理论上它不会有缺点,作为一种极端的解决方法,您可能会更改所有涉及的表以将其 CHAR 类型重新定义为 VARCHAR2 (如果您有权这样做,并且这是可行的)。
\n| 归档时间: |
|
| 查看次数: |
793 次 |
| 最近记录: |