【问题标题】:How to get values from a ResultSet generically?一般如何从 ResultSet 中获取值?
【发布时间】:2013-06-27 08:04:23
【问题描述】:

我需要从ResultSet 中检索值以通过反射使用它们来调用构造函数。 我正在尝试使用 Class.cast(Object),但我总是得到一个 InvalidCastException

这就是我所拥有的:

    Object[] args = new Object[count];
    Class<?>[] arr = co.getParameterTypes(); 
    for(i = 0; i<args.length; i++){

        args[i] = arr[i].cast(rs.getObject(i+1));
    }

    Object t;

    try {
        t = co.newInstance(args);
    } catch (Exception e) {
        throw new RuntimeException(e); 
    }

    return (T)t;

co 是构造函数,rs 是我已经拥有的ResultSet

【问题讨论】:

  • 你能提供更多的上下文吗?表、SQL 选择和/或co 的类?
  • 上下文是为动态代理创建一个通用转换器。此转换器会将 ResultSet 转换为他知道的域实体。我们目前正在使用 Northwind 进行此尝试,并且该表可以是该数据库中的任何一个。构造函数类同样可以是我们应用中 Northwind 的任何域实体。
  • 所以co 可以有效地属于任何类别,这就是你的意思吗?
  • 是的,就是这样。我们为建模 Northwind 创建的任何类
  • 如果没有演员阵容会怎样?

标签: java generics jdbc resultset


【解决方案1】:

即使你可以让它工作,也存在一个长期维护的噩梦,即对象构造函数中的参数顺序可能与ResultSet(RDB 中的表)中的列顺序不匹配。例如,如果您的 Person 对象有一个构造函数,该构造函数采用 firstName、lastName,则 DB 表中列的顺序可能不匹配。可能是 LAST_NAME、FIRST_NAME,甚至可能是 FIRST_NAME、SOME_COLUMN_YOU_DONT_CARE_ABOUT、LAST_NAME。

在我看到的更通用地处理这个问题的代码中,他们使用域对象(例如 Person)的反射来获取属性名称(在我的例子中,他们查看的是 setter,而不是构造函数,YMMV),然后尝试使用ResultSet.getMetaData() 将它们与ResultSet 列名匹配。

【讨论】:

  • 我们几乎涵盖了这部分,现在唯一真正的问题是实际上能够通过 getObject 方法从 ResultSet 中获取“事物”,然后将这些对象作为参数传递给构造函数。由于 SQL 类型系统与 Java 中的不同,我们总是会遇到 CastException。不使用 ResultSet 的 getString、getInt、getDouble 等方法,我们如何做到这一点。
  • 我认为你需要在 Java 类型和 SQL 类型 getInt、getDouble 等之间有一系列令人讨厌的 if/else 语句(或 switch)映射......但是因为它都在一个中心放置它会为您节省很多痛苦。
  • 您也可以编写自己的与 java.sql.Types 对应的枚举,这样可以做到这一点是一种相当干净的 O-O 方式。 Oracle for Java 9 的注意事项:请制作 java.sql.Types 的枚举版本!
猜你喜欢
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多