Нет общего интерфейса для java.sql.ResultSet, CallableStatement, SQLInput - PullRequest
3 голосов
/ 19 декабря 2010

Это ситуация

В 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.И есть много подобных примеров

Мой вопрос

  • Кто-нибудь знает библиотеку расширений JDBC, которая элегантно решает эту проблему?
  • Или мне самому написать простой класс-оболочку (или адаптер) для всех этих типов?
  • Или вы просто согласитесь с этим и продолжите дублировать внутренний код библиотеки?

Какое решение вы предпочитаете и почему? Спасибо за любой отзыв

Ответы [ 3 ]

3 голосов
/ 19 декабря 2010
  • Кто-нибудь знает библиотеку расширений 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 голос
/ 19 декабря 2010

Лично я бы не использовал такую ​​вещь. Я не вижу, чтобы вы делали мою жизнь намного проще с помощью этой абстракции.

Я не думаю, что есть причина, по которой абстракции SQL просачиваются из уровня персистентности. Я делаю вызов, сопоставляю объекты и закрываю абстракции SQL. Ты говоришь так, будто хочешь, чтобы они торчали, а это плохая идея.

Я думаю, что пользователи Spring сделали использование JDBC настолько простым, насколько это возможно. Я могу ошибаться, но я не вижу причин идти по пути, который ты предлагаешь.

Если я посмотрю на javadocs для SQLInput, я увижу это:

Этот интерфейс используется только для пользовательских отображение, используется драйвером позади сцены, а программист никогда напрямую вызывает методы SQLInput.

Я не уверен, почему вы считаете необходимым выставить этот интерфейс.

Что касается ResultSet и CallableStatement (или любого оператора в этом отношении), то они могут в конечном итоге вернуть один или несколько ResultSet для возврата результатов запроса. Я бы предпочел увидеть абстракцию вокруг этого. Я полагаю, что вы мутите воду, обнажая других. Я бы не рекомендовал это.

Возможно, тот факт, что это никогда не было сделано, является еще одним свидетельством того, что этого не следует делать. Но вы можете сделать это и посмотреть, проголосует ли рынок за вас.

0 голосов
/ 19 декабря 2010
  1. Не уверен в расширении для JDBC.
  2. Класс оболочки или шаблон посетителя могут быть полезны в зависимости от остальной части вашего дизайна.
  3. Как насчет расширения каждого из них и обеспечения его реализации того же интерфейса, который имеет те же сигнатуры методов, чтобы получить нужные данные.
...