java.sql.ResultSet、CallableStatement、SQLInput没有通用接口 情况就是这样
在本文中,非常需要对JDBC进行抽象。我希望jOOQ客户机代码不知道这样一个事实:一些数据是从简单的ResultSet检索的,一些数据是从SQLInput(对于UDT)检索的,或者是从CallableStatements(对于存储过程/函数)检索的。因此,我想在这些JDBC类型上添加抽象:java.sql.ResultSet、CallableStatement、SQLInput没有通用接口 情况就是这样,java,jdbc,jooq,Java,Jdbc,Jooq,在本文中,非常需要对JDBC进行抽象。我希望jOOQ客户机代码不知道这样一个事实:一些数据是从简单的ResultSet检索的,一些数据是从SQLInput(对于UDT)检索的,或者是从CallableStatements(对于存储过程/函数)检索的。因此,我想在这些JDBC类型上添加抽象: java.sql.ResultSet java.sql.CallableStatement java.sql.SQLInput java.sql.SQLOutput 现在,它们的工作方式基本相同。对于jav
java.sql.ResultSet
java.sql.CallableStatement
java.sql.SQLInput
java.sql.SQLOutput
现在,它们的工作方式基本相同。对于java.sql.Types
中的每个数据类型,它们通常都有get
和set
方法。例如,它们附带了如下方法
BigDecimal getBigDecimal(int index);
int getInt(int index);
boolean wasNull();
他们都有类似的方法
BigDecimal getBigDecimal(int index);
int getInt(int index);
boolean wasNull();
问题
不幸的是,这些JDBC接口并没有扩展一个通用接口,这使得那些想要编写像下面这个代码片段这样的通用JDBC代码的人的生活更加轻松(只是一个支持我的问题的示例):
以上代码需要为这三种类型编写,ResultSet
,CallableStatement
,SQLInput
。还有很多类似的例子
我的问题是
- 有人知道一个JDBC扩展库可以优雅地解决这个问题吗李>
- 或者我应该自己为所有这些类型编写一个简单的包装器类(或适配器)
- 或者你会接受这个事实,继续复制内部库代码吗
- 有人知道一个JDBC扩展库可以优雅地解决这个问题吗
- 或者我应该自己为所有这些类型编写一个简单的包装器类(或适配器)
public interface DataProvider {
public BigInteger getBigInteger(int columnIndex);
// ...
}
让所有具体的包装器来实现它
public class ResultSetDataProvider implements DataProvider {
private ResultSet resultSet;
public ResultSetDataProvider(ResultSet resultSet) {
this.resultSet = resultSet;
}
public BigInteger getBigInteger(int columnIndex) {
BigDecimal bigDecimal = resultSet.getBigDecimal(columnIndex);
return bigDecimal != null ? bigDecimal.toBigInteger() : null;
}
// ...
}
用它来代替
try {
// Acquire ResultSet.
DataProvider dataProvider = new ResultSetDataProvider(resultSet);
// Process DataProvider.
} finally {
// Close ResultSet.
}
- 或者你会接受这个事实,继续复制内部库代码吗
不,我不会。保留您的代码。就我个人而言,我不会使用这种东西。我看不出你用这个抽象概念让我的生活轻松多了 我认为SQL抽象没有理由从持久层泄漏出去。我进行调用,映射到对象,并关闭SQL抽象。你听起来好像想让他们留下来,这是个坏主意 我认为Spring的人们已经使使用JDBC变得尽可能简单。我可能错了,但我看不出有什么理由走你建议的路 如果我看一下javadocs for SQLInput,我会看到: 此接口,仅用于自定义 映射,由后面的驾驶员使用 场景,程序员永远不会 直接调用SQLInput方法 我不知道你为什么认为有必要公开这个接口
public interface DataProvider {
public BigInteger getBigInteger(int columnIndex);
// ...
}
至于ResultSet和CallableStatement(或任何语句),它们最终可以返回一个或多个ResultSet以返回查询结果。我宁愿看到一个抽象的说法。我相信你把其他的都暴露出来是在把水弄脏。我不推荐
也许这件事从来没有做过,这是另一个不应该做的迹象。但是欢迎你这么做,看看市场是否投票给你一个赢家。这不是适配器设计模式的目的吗?@Skaffman,你的意思可能和我说的“包装类”一样……我不确定访问者模式。据我所知,这主要用于访问数据结构中的节点,对于任何设计来说,这通常都是多余的。扩展每一个,让扩展实现相同的接口,这将是一个“包装类”。访问者模式可以在访问节点之外使用,但我也不知道您的设计的其余部分是什么样子,所以这可能不合适。包装器类只包含该类的一个实例并对其进行调用。这与扩展对象并实现附加接口不同。好的,关于访问者和扩展,您是对的。但在这里,扩展不是一个选项。我们讨论的是ResultSet、CallableStatement等。具体实现是一个JDBC驱动程序特定的类,例如oracle.JDBC.driver.OracleResultSetImpl。我不能/不想扩展该类。我不确定我是否理解您所指的“SQL抽象”。是一般的jOOQ,还是仅上述声明?因为上述陈述是jOOQ内部的一个例子。当然,所有JDBC对象都已正确关闭,但出于本示例的目的,我省略了99%的jOOQ代码;-)此外,jOOQ远远超出了spring人员对JDBC所做的工作。比较SpringJDBC示例()和jOOQ示例()可能不是一个正确的比较,因为Spring已经升级到3.1版。我不确定我是否会买它,因为Spring比jOOQ更具吸引力。这是我第一次听说它。根据我所看到的,我肯定我现在不感兴趣,但也许有一天。你对春季版的看法是对的。我的错。不过,3.1中的功能集似乎没有本质上的不同。当然,你对任何第三方软件都有自己的看法,但是既然你已经花了时间来表达这个观点,也许你仍然可以考虑实际问题本身?)实际上,这是一个相当技术性的问题,我考虑了实际问题。我和任何回答过的人都不知道这样的事;有些人认为,这需要发明。如果有人做了,我对做这样的事情或使用它不感兴趣。我得到的抽象对于m来说已经足够了