【问题标题】:Why rsmd.getColumnClassName(index) showing strange results为什么 rsmd.getColumnClassName(index) 显示奇怪的结果
【发布时间】:2018-02-17 17:18:05
【问题描述】:

我正在尝试通过 Java 从 Oracle EMP 表中提取数据(在原始表中添加了一列,数据类型为 TIMESTAMPTZ)。 当我尝试使用以下方法通过 java 查找数据类型时,它显示的结果与我预期的不同。

System.out.println(rsmd.getColumnName(index)+"-->"+rsmd.getColumnType(index)+"-->"+rsmd.getColumnClassName(index)+"  ");

这是输出

EMPNO-->2-->java.math.BigDecimal  
ENAME-->12-->java.lang.String  
JOB-->12-->java.lang.String  
MGR-->2-->java.math.BigDecimal  
HIREDATE-->93-->java.sql.Timestamp  
SAL-->2-->java.math.BigDecimal  
COMM-->2-->java.math.BigDecimal  
DEPTNO-->2-->java.math.BigDecimal  
TSTMP-->-101-->oracle.sql.TIMESTAMPTZ  

1) "2" 对应 java.sql.Types 中的 Numeric。 这里它显示了 EMP 表中的 NUMBER 和 NUMBER(7,2) 列,为什么显示 java.math.BigDecimal 的类我认为是小数(在这种情况下为 NUMBER(7,2))。

2) 我也没有在 java 类型中看到 TIMESTAMPTZ。 Oracle JDBC 正在处理它。 java不是支持所有的oracle DataTypes吗?

我正在将此数据写入另一个表。所以最后我决定在我的代码中使用 Object 将所有内容留给 java 进行转换。

if(obj instanceof java.math.BigDecimal)
     tgtSt.setObject(index, obj);
else if(obj instanceof java.lang.String)
    tgtSt.setObject(index, obj);
else if(obj instanceof java.sql.Timestamp)
   tgtSt.setObject(index, obj);
else if(obj instanceof oracle.sql.TIMESTAMPTZ)
  tgtSt.setObject(index, obj);

3) 这种使用对象的方法会有什么问题吗? 4) 此外,当 getObject() 和 setObject() 方法完成工作时,为什么我们还有其他方法,如 getInt() getString()..... 请帮我解决这些问题。

【问题讨论】:

标签: java resultset


【解决方案1】:

为什么类显示 java.math.BigDecimal

检查The JDBC API Specification 4.2

第 192 页的表 B-3 显示了 从 JDBC 类型到 Java 类型的标准映射,其中包括:

+------------------+-----------------------+
| JDBC Type        |        Java Type      |
+------------------+-----------------------+
| NUMERIC          |  java.math.BigDecimal |
+------------------+-----------------------+

即所有数值类型都通过defautl映射到java.math.BigDecimal


我也没有在 java 类型中看到 TIMESTAMPTZ

TIMESTAMPTZ类型(TIMESTAMP WITH TIME ZONE)在SQL标准中没有定义,是Oracle专有的类型,在JDBC规范中找不到。

请咨询Oracle Database JDBC Developer's Guide

A-1 Valid SQL Data Type-Java Class Mappings 显示了驱动程序实现的所有允许的数据映射,您可以在那里看到TIMESTAMP WITH TIME ZONE 映射到oracle.sql.TIMESTAMPTZ 类,该类在java.sql 包中不可用,但它是封装在驱动程序jar 中的内部类。


3) 这种使用对象的方式会有什么问题吗?

像往常一样,答案是视情况而定。你可以这样做,但它会很乏味且容易出错,我不知道这样做的原因是什么,这就像重新发明轮子一样。
有很多工具和框架提供开箱即用的 JDBC/Java 类型映射和转换,从基本的 PreparedStatement and ResultSet 开始,到 Spring's JDBCTemplate,直到 JPA/Orm 框架,如 HibernateEclipselinkMyIbatis

【讨论】:

  • 感谢 krokodilko。你的解释对我有帮助。非常感谢
猜你喜欢
  • 2016-02-13
  • 2014-01-27
  • 2016-10-04
  • 1970-01-01
  • 2015-01-13
  • 2018-05-28
  • 2016-11-19
  • 1970-01-01
  • 2013-07-14
相关资源
最近更新 更多