【问题标题】:Encapsulating JDBC resultset封装 JDBC 结果集
【发布时间】:2014-08-24 14:23:56
【问题描述】:

我有一个非常常见的封装问题。我正在通过 jdbc 查询一个表,需要将记录保存在内存中一段时间​​以进行处理。我没有任何休眠 POJO 用于同一个表来创建任何对象并保存。我说的是单个负载 2 亿询问。

常见的方法是创建一个对象数组并在需要使用它们时进行转换。 (假设,我可以获得将保存在一些参考表中的列名和数据类型等表详细信息..)但是这种方法将非常昂贵(时间)我想当考虑到负载时..

任何好的方法将不胜感激......

【问题讨论】:

  • 我关心的是处理时间,假设我在系统中有足够的内存......
  • 您将需要 大量 内存才能在内存中保存 2 亿行。
  • 暂时忘记内存..我可以触发多个查询并创建线程...问题是如何在不创建对象数组的情况下将记录保存在内存中。如果我能避免的话会很好类型转换项目的时间,因为每条记录中会有很多列
  • 你可能猜错了类型转换非常昂贵,请参阅stackoverflow.com/a/8803559/3080094

标签: java arrays jdbc resultset encapsulation


【解决方案1】:

好吧,如果您需要 200m 个对象在内存中,那么您可以在遍历 ResultSet 时初始化每个对象 - 您不需要保存元数据

 ResultSet rs = stmt.executeQuery();
 while (rs.next()) {
    String col1= rs.getString("col1");
    Integer col2= rs.getInt("col2");
    MyClass o = new MyClass(col1,col2);
    add(o);
 }
 rs.close();

【讨论】:

  • 不,伙计,我不能这样做。我无法创建一个类(您的示例中的 MYClass)并部署它。我已经提到我没有为相关表创建 POJO。
  • 为了更清楚,所涉及的表是完全可配置的。这就是为什么我不能在这个任务之前创建 POJO 类。
【解决方案2】:

为了更清楚,所涉及的表是完全可配置的。 这就是为什么我不能在这个任务之前创建 POJO 类。

在这种情况下,我认为这样做的唯一真正方法是将每一行转换为带有分隔符(CSV、XML 或其他内容)的字符串,然后创建一个字符串数组。

您可以得到一个 JDBC 查询返回的列名列表,如下所示:

Retrieve column names from java.sql.ResultSet

【讨论】:

  • 感谢您的回答..但这又是一个耗时的问题..正如我之前提到的,我将使用这些记录进行处理..在这种情况下,假设我要存储它作为分隔字符串,然后每次我必须解析字符串以获取各个列。然后我必须再次将字符串转换为所需的数据类型,这与将数据存储在对象数组中或多或少相同......这有意义吗??
  • 或许这需要换个角度来看。你需要做什么样的处理?
  • 我将做一些商业计算。我不想把这里的事情复杂化。简而言之,我将记录并根据一些键将其拆分为多个...
【解决方案3】:

听起来像CachedRowSet 可以在这里解决问题。这几乎正​​是你想要的。它需要一个 ResultSet 并将整个事情吸干,然后您可以在闲暇时处理它。

附录:

我真的在寻找一个强大的记录保持者,可以轻松访问成员

但这几乎就是 CachedRowSet 的本质。

它管理具有命名(和编号)列的记录集合,并提供对这些列的类型化访问。

CachedRowSet crs = getACachedRowSet();
crs.absolute(5) // go to 5th row, shows you have random access to the contents.
String name = crs.getString("Name");
int age = crs.getInt("Age");
date dob = crs.getDate("DateOfBirth");

虽然我确信您可以自己制作一些东西,但 CachedRowSet 可以为您提供您所要求的一切。如果您不想将数据实际加载到 RAM 中,则可以使用 ResultSet。

唯一的缺点是它不是线程安全的,因此您需要围绕它进行同步。但这就是生活。 CachedRowSet 究竟如何满足您的需求?

【讨论】:

  • 感谢您的 cmets..但我担心它不会帮助我。让我用一个例子来说明清楚。假设该表具有名称、年龄和出生日期列。现在结果集有三行。我不想缓存它,因为我的处理可以线程化,甚至我可以触发多个查询。我将如何将这三列存储在内存中,并在需要时使用它们而不会出现并发症。对象数组是一种解决方案,但类型转换是问题所在。我真的在寻找一个强大的记录保持者,可以轻松访问成员
  • 如果我可以动态编译并保持一个类并处理它(创建该类对象的数组),它就会解决问题。但要做到这一点,我应该尝试反射和所有,这将是一个开销。我只是想知道是否有其他更好的方法。
  • 我知道 CachedRowSet..但是正如我之前提到的,我的内存没有任何问题..我可以处理结果集..
  • 怎么知道name的类型是String。就我而言,我不会知道这一点,因此我不能调用 getString。例如,一行将是 James,25,10/10/1988 - 我怎么知道第一个是字符串,下一个是 int,第三个是日期......列数是可配置的,它可以变化......我可能知道列名和类型..
  • 您可以从 RowSet 中获取元数据,这些数据会告诉您列的类型(由数据库报告)。
猜你喜欢
  • 2011-11-21
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2011-05-14
相关资源
最近更新 更多