Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.sql.ResultSet、CallableStatement、SQLInput没有通用接口 情况就是这样_Java_Jdbc_Jooq - Fatal编程技术网

java.sql.ResultSet、CallableStatement、SQLInput没有通用接口 情况就是这样

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

在本文中,非常需要对JDBC进行抽象。我希望jOOQ客户机代码不知道这样一个事实:一些数据是从简单的ResultSet检索的,一些数据是从SQLInput(对于UDT)检索的,或者是从CallableStatements(对于存储过程/函数)检索的。因此,我想在这些JDBC类型上添加抽象:

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是否有扩展
  • 包装器类或访问者模式可能有用,具体取决于设计的其余部分
  • 扩展每个接口,使它们实现具有相同方法签名的相同接口,以获取所需的数据
    • 有人知道一个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来说已经足够了