【问题标题】:Is it possible to map basic JDBC SQL types to a Java class?是否可以将基本 JDBC SQL 类型映射到 Java 类?
【发布时间】:2014-08-22 23:39:00
【问题描述】:

当使用 getObject 方法从 ResultSet 对象中检索列时,类由 JDBC 驱动程序选择。我正在寻找一种方法来选择在运行时检索列的类。

在下面的示例中,类型 Class1 是使用作为整数的变量 T 创建的。

Class Class1<T>
{
  public T getColumn(DataSource ds)
  {
    T value = null;
    Connection con = null;

    try
    {
      con = ds.getConnection();
      Statement st = con.createStatement();
      ResultSet rs = st.executeQuery("select 1 from dual");
      rs.next();
      Object o = rs.getObject(1); // I want an Integer but a BigDecimal is created!
      value = (T) o; // ClassCastException here!
      rs.close();
      st.close();
    }
    finally
    {
      if (con != null) { con.close(); }
    }

    return i;
  }
}

ResultSet 类提供了一个名为 getObject 的方法,该方法接受一个列参数和一个类型 Map 参数。此类型 Map 仅用于 UDT(用户定义类型)。我也需要将此功能应用于基本 SQL 类型。我知道我可以使用 switch/case 语句来解决这个问题,但我试图避免这种情况。这可能吗?

编辑

我应该提到我使用的是 Java 1.6。看起来这可能已在 1.7 中解决。感谢 JB Nizet 的参考。

【问题讨论】:

  • 我想知道演员 (T) 是如何工作的。由于类型擦除,我希望演员表不起作用。甚至还有一个常见的解决方法:将所需的类型作为类对象传递给方法。见stackoverflow.com/questions/14524751/…
  • 您是否有理由不使用更高级别的 API 进行数据访问?
  • JB - 谢谢,但我忘了提到我使用的是 Java 1.6.Ben,你能说得更具体点吗?
  • 您能否提供一个示例,说明为什么直到运行时才知道列类型?看来您应该始终在编译时知道列的类型。

标签: java jdbc


【解决方案1】:

您可能必须编写自己的代码。您可能必须对收到的数据进行强制转换。为了避免切换/大小写,您可以使用像 Hibernate 这样的精确 ORM 工具,这将允许您的 Pojo 具有与表列类似的精确名称,并且它们会自动使用列中的数据填充您的 Pojo。在此之后,您可以为每一列编写数据转换代码。像 Hibernate 这样的 ORM 工具,MyBatis 会为你做映射。

【讨论】:

    【解决方案2】:

    JB Nizet 为 Java 1.7 提供了答案:http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html#getObject-int-java.lang.Class-

    对于早期版本的 Java,DolphinJava 是正确的。我将不得不编写自己的代码。

    我是如何解决的

    与上面使用 Class1 的示例保持一致,我创建了扩展 Class1 的子类,其中 T 是所需的类型,然后创建了调用 getColumn 的特定类型方法Class1 中的方法:

    public Class1<T>
    {
      public Object getColumn(DataSource ds)
      {
        Object o        = null;
        Connection con  = null;
    
        try
        {
          con           = ds.getConnection();
          Statement st  = con.createStatement();
          ResultSet rs  = st.executeQuery("select 1 from dual");
          rs.next();
          Object o      = rs.getObject(1);
          rs.close();
          st.close();
        }
        finally
        {
          if (con != null) { con.close(); }
        }
    
        return o;
      }
    }
    
    Class1Integer extends Class1<Integer>
    {
      public Integer getIntegerColumn()
      {
        Object o  = getColumn(datasource);
        Integer i = new Integer(o);
        return i;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-29
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 2011-03-11
      • 2012-02-20
      • 1970-01-01
      相关资源
      最近更新 更多