如何用Java从数据库中读取UDT(用户定义类型)的最佳方法?

7
我认为我对UDT和JDBC的了解已经很全面了,直到SO上的某个人向我指出了java.sql.SQLInputjava.sql.SQLData 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,包括适当的 getters/setters 和其他属性。
我的问题:
  • 您认为我采用实现SQLData的方法可行吗?即使Javadoc声明不同?
  • 你知道哪些其他读取Java中UDT的方法?例如Spring做什么?Hibernate做什么?JPA做什么?你自己又做了什么?
补充说明:

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

3个回答

4
配置驱动程序以在后台工作的优点是程序员不需要将类型映射传递到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的基于注释的方法的文章:http://andrejusb.blogspot.com/2007/12/oracle-spatial-and-toplink-11g.html - richj
对于这个有趣的反馈,特别是JBoss的方法,我给一个赞。对于我的需求,无论类型映射是在每个getObject(...)调用上提供还是在连接全局提供都是细节问题。两种方法都有优缺点。在我的情况下,我无法控制连接,因为我正在使用jOOQ库(http://jooq.sourceforge.net)。另一方面,我将ResultSet的具体调用从库的客户端代码中隐藏...(示例在http://tinyurl.com/3aaxdoj中) - Lukas Eder

1

谢谢,这是有趣的反馈。看起来为了一个单独的列需要做很多手动工作... - Lukas Eder
确实,这是很多工作。你可以通过使用一些默认值的智能基类来使它变得更容易。使用Hibernate API本身来做这件事肯定有点啰嗦。 - Arjan Tijms
它表明我的数据库接口库(http://jooq.sourceforge.net)确实提供了实际需求的解决方案。我正在尝试通过源代码生成来解决这个问题。生成的源代码可以轻松直观地使用,因为UDT得到了本地支持。 - Lukas Eder

-2

我知道 Spring 的作用:你编写他们 RowMapper 接口的实现。我从来没有在 Spring 中使用过 SQLData。你的帖子是我第一次听说或考虑过那个接口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接