在jOOQ中,需要对JDBC进行抽象。我希望jOOQ客户端代码不知道这样的事实,即从一个简单的ResultSet中检索一些数据,从SQLInput(对于UDT)或从CallableStatements(对于存储过程/函数)检索一些数据。因此,我想在这些JDBC类型上添加抽象:
java.sql.ResultSet
java.sql.CallableStatement
java.sql.SQLInput
java.sql.SQLOutput
现在他们的工作方式几乎相同。对于get
中的每种数据类型,它们通常都有set
和java.sql.Types
方法。例如,它们带有像
BigDecimal getBigDecimal(int index);
int getInt(int index);
他们都有像
这样的方法boolean wasNull();
不幸的是,这些JDBC接口没有扩展单个公共接口,这使得想要在这里编写通用JDBC代码的人更容易生活(这只是支持我的问题的一个例子):
// As JDBC has no support for BigInteger types directly,
// read a BigDecimal and transform it to a BigInteger
BigDecimal result = null;
if (source instanceof ResultSet) {
result = ((ResultSet) source).getBigDecimal(index);
}
else if (source instanceof CallableStatement) {
result = ((CallableStatement) source).getBigDecimal(index);
}
else if (source instanceof SQLInput) {
result = ((SQLInput) source).readBigDecimal();
}
return result == null ? null : result.toBigInteger();
上述代码需要为所有这三个代码编写,ResultSet
,CallableStatement
,SQLInput
。还有很多类似的例子
您更喜欢哪种解决方案?为什么?感谢您提供反馈
答案 0 :(得分:3)
- 有没有人知道一个优雅地解决这个问题的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.
}
- 或者你会接受这个事实并继续复制内部库代码吗?
不,我不会。保留您的代码DRY。
答案 1 :(得分:1)
就个人而言,我不会使用这样的东西。我没有看到你通过这种抽象让我的生活更轻松。
我认为SQL抽象没有从持久层漏出的原因。我进行调用,映射到对象,并关闭SQL抽象。你听起来像是希望他们坚持下去,这是一个坏主意。
我认为Spring的人们已经尽可能地使用JDBC了。我可能是错的,但我没有理由沿着你建议的路走下去。
如果我查看SQLInput的javadocs,我会看到:
此界面仅用于自定义 映射,由后面的驱动程序使用 场景,程序员永远不会 直接调用SQLInput方法。
我不确定为什么你认为有必要公开这个界面。
对于ResultSet和CallableStatement(或任何Statement,就此而言),那些最终可以返回一个或多个ResultSet来返回查询结果。我宁愿看到围绕它的抽象。我相信你通过揭露其他人来淹没水域。我不推荐它。
或许它从未被完成的事实是另一个迹象表明它不应该被完成。但欢迎你这样做,看看市场是否会为你赢得胜利。
答案 2 :(得分:0)