【问题标题】:What's the best way to read a UDT from a database with Java?使用 Java 从数据库中读取 UDT 的最佳方法是什么?
【发布时间】:2011-05-28 00:15:12
【问题描述】:

我以为我对 UDT 和 JDBC 了如指掌,直到 SO 上的某个人向我指出了 java.sql.SQLInputjava.sql.SQLData JavaDoc 的 Javadoc 的一些细节。该提示的本质是(来自 SQLInput):

包含流的输入流 代表一个实例的值 SQL 结构化类型或 SQL 不同的类型。这个接口,用过 仅用于自定义映射,由 幕后的司机,还有一个 程序员从不直接调用 SQLInput 方法。

这与我过去所做的完全相反(当与 Oracle JDBC 驱动程序一起使用时,它在生产系统中也使用且稳定):实现 SQLData 并在自定义映射中提供此实现到

ResultSet.getObject(int index, Map mapping)

然后,JDBC 驱动程序将使用我的自定义类型回调

SQLData.readSQL(SQLInput stream, String typeName)

方法。我实现了这个方法并从SQLInput 流中读取每个字段。最后,getObject() 将返回我的 SQLData 实现的正确初始化实例,其中包含来自 UDT 的所有数据。

对我来说,这似乎是实现这种自定义映射的完美方式。这样做的充分理由:

  • 我可以使用标准 API,而不是使用供应商特定的类,例如 oracle.sql.STRUCT 等。
  • 我可以从我的 UDT 生成源代码,具有适当的 getter/setter 和其他属性

我的问题

  • 您如何看待我实施SQLData 的方法?即使 Javadoc 另有说明,它是否可行?
  • 您知道在 Java 中读取 UDT 的其他哪些方法?例如。春天做什么?休眠是做什么的? JPA 是做什么的?你是做什么的?

附录

UDT 支持和与存储过程的集成是jOOQ 的主要功能之一。 jOOQ 旨在从客户端代码中隐藏更复杂的“JDBC 事实”,而不隐藏底层数据库架构。如果您有类似上述的问题,jOOQ 可能会为您提供答案。

【问题讨论】:

    标签: java jdbc user-defined-types


    【解决方案1】:

    配置驱动程序使其在幕后工作的优点是程序员不需要将类型映射传递给 ResultSet.getObject(...),因此需要记住的细节更少(大多数时候)。还可以在运行时使用属性配置驱动程序来定义映射,因此应用程序代码可以独立于 SQL 类型到对象映射的细节。如果应用程序可以支持多个不同的数据库,则可以为每个数据库支持不同的映射。

    您的方法是可行的,其主要特点是应用程序代码使用显式类型映射。

    在幕后方法中,ResultSet.getObject(int) 方法将使用连接上定义的类型映射,而不是应用程序代码在 ResultSet.getObject(int index, Map mapping) 中传递的类型映射。否则方法相同。

    其他方法

    我已经看到基于这些类的 JBoss 4 使用的另一种方法:

    org.jboss.ejb.plugins.cmp.jdbc.JDBCParameterSetter 
    org.jboss.ejb.plugins.cmp.jdbc.JDBCResultSetReader.AbstractResultSetReader
    

    想法相同,但实现是非标准的(它可能早于定义 SQLData/SQLInput 的 JDBC 标准版本)。

    【讨论】:

    • 我还发现了一篇关于 TopLink 使用的基于注释的方法的帖子:andrejusb.blogspot.com/2007/12/…
    • +1 对于这个有趣的反馈,尤其是 JBoss 方法。对于我的需要,是否在每个 getObject(...) 调用或全局连接上提供类型映射这一事实是一个细节。两种方法各有利弊。就我而言,我无法控制连接,因为我在 jOOQ 库 (jooq.sourceforge.net) 中使用它。另一方面,我从库的客户端代码中隐藏了对 ResultSet 的具体调用...(tinyurl.com/3aaxdoj 中的示例)
    【解决方案2】:

    您还知道哪些其他在 Java 中读取 UDT 的方法?例如。春天做什么?休眠是做什么的? JPA 是做什么的?你是做什么的?

    另一个问题的答案中显示了如何在 Hibernate/JPA 中完成类似操作的示例:

    Java Enums, JPA and Postgres enums - How do I make them work together?

    【讨论】:

    • 谢谢,这是有趣的反馈。看起来只有一列需要做很多手动工作,不过......
    • 确实,工作量很大。您可以通过使用具有一些默认值的智能基类来使其更容易一些。执行此操作的 Hibernate API 本身确实有点冗长。
    • 这表明我的数据库接口库(jooq.sourceforge.net)确实提供了满足实际需求的解决方案。我正在尝试解决源代码生成问题。然后可以轻松直观地使用生成的源代码,因为 UDT 是本机支持的。
    【解决方案3】:

    我知道 Spring 做了什么:你编写他们的 RowMapper 接口的实现。我从未在 Spring 中使用过 SQLData。你的帖子是我第一次听说或想到这个界面。

    【讨论】:

      猜你喜欢
      • 2010-09-24
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 2020-01-16
      相关资源
      最近更新 更多