2016-07-05 4 views
0

Я использую JDBC с MySQL-разъем-Java-6.0.2.jar, и, если я не делаю что-то неправильно, я думаю, что реализация DatabaseMetaData.ownDeletesAreVisible и DatabaseMetaData.deletesAreDetected действует как-то непоследовательно между собой.DatabaseMetaData.ownDeletesAreVisible против DatabaseMetaData.deletesAreDetected Противоречия

Вот что говорит о спецификации JDBC ownDeletesAreVisible:.

"... Если удаленная строка удаляется или заменяется на пустую строку, метод DatabaseMetaData.ownDeletesAreVisible (интермедиат типа) возвращает истину, он возвращается ложь, если объект ResultSet содержит еще удаляемой строки, что означает, что удаление не видно как изменение ResultSet объектов данного типа ... «

И о deletesAreDetected:

» .. . МЕТ спосо deletesAreDetected возвращает ложь, если строка удаляется из объекта ResultSet удаляется из него и верно, если удаляется строка заменяется пустой или недопустимой строки ... "

Я добавил выходы в качестве комментариев:

import static java.sql.ResultSet.CONCUR_UPDATABLE; 
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; 
import java.sql.*; 

public class Deletions { 

    public static void main(String[] args) throws SQLException { 

     try (Connection conn = DBUtils.getConnection(); 
       Statement stmt = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE); 
       ResultSet rs = stmt.executeQuery("select * from book")) { 

      DatabaseMetaData dbmd = conn.getMetaData(); 

      //prints false 
      System.out.println(dbmd.ownDeletesAreVisible(TYPE_SCROLL_INSENSITIVE)); 

      // prints false. Controversy? 
      System.out.println(dbmd.deletesAreDetected(TYPE_SCROLL_INSENSITIVE)); 

      // Prints everything including foo 
      printAll(rs); 


      // deletes foo 
      while (rs.next()) { 
       String title = rs.getString(2); 
       if (title.equalsIgnoreCase("foo")) { 
        rs.deleteRow(); 
       } 
      } 

      // Prints everything without foo 
      printAll(rs); 

     } 
    } 

     private static void printAll(ResultSet rs) throws SQLException { 
      rs.beforeFirst(); 
      while (rs.next()) { 
       System.out.println(rs.getString(2)); 
      } 
      rs.beforeFirst(); 
     } 
} 
+0

Вы должны действительно переместить свои комментарии в текст, что значительно облегчает чтение. –

+0

Благодарим вас за советы. Готово. –

ответ

0

Мой Вывод:

  • Использование MYSQL:

dbmd.ownDeletesAreVisible (TYPE_SCROLL_INSENSITIVE) ВЕРНУЛСЯ FALSE: »... Это возвращает ложь, если объект ResultSet содержит еще удаляемой строки. .. "

dbmd.deletesAreDetected (TYPE_SCROLL_INSENSITIVE) ВЕРНУЛСЯ FALSE: " ... повторно оказывается ложным, если строка удаляется из объекта ResultSet из него удаляется ...»

Результаты:

ResultSet rs = stmt.executeQuery("select * from book"); 

printAll(rs); // Prints everything including foo 

// deletes foo 
while (rs.next()) { 
    String title = rs.getString(2); 
    if (title.equalsIgnoreCase("foo")) { 
     rs.deleteRow(); 
    } 
} 

printAll(rs); // Prints everything without foo. Makes no sense. 
  • Использование Apache Derby DB:

dbmd.ownDeletesAreVisible (TYPE_SCROLL_INSENSITIVE) RETURNED TRUE: «... Если удаленная строка удалена или заменена пустой строкой, метод вернет true ...»

dbmd.deletesAreDetected (TYPE_SCROLL_INSENSITIVE) ВЕРНУЛСЯ TRUE: "... Метод возвращает истину, если удаляемая строка заменяется пустой или недопустимой строки ..."

Результаты:

ResultSet rs = stmt.executeQuery("select * from book"); 

printAll(rs); // Prints everything including foo 

// deletes foo 
while (rs.next()) { 
    String title = rs.getString(2); 
    if (title.equalsIgnoreCase("foo")) { 
     rs.deleteRow(); 
    } 
} 

/* Prints 'null' instead of 'foo' here. Now this makes sense */  
printAll(rs); 

Вывод:

Эта реализация MySQL не соответствовала спецификации JDBC должным образом. Два вышеупомянутых метода противоречат друг другу, а также против выходов.

Apache Derby DB должным образом реализует спецификации JDBC.

0

это не противоречие, то JDBC 4.2 specification, раздел 15.2.4.2 говорит (курсив мой):

После метода deleteRow была вызвана, текущая строка будет удалена в базовом источнике данных. Это удаление отображается как изменение в открывшемся объекте, если строка удалена или заменена пустой или недопустимой строкой.

Если удаленная строка удаляется или заменяется пустой строке, метод DatabaseMetaData.ownDeletesAreVisible(int type) будет возвращать true. Это возвращает false, если объект ResultSet по-прежнему содержит удаленную строку, что означает, что удаление не отображается как изменение объектов ResultSet данного типа.

[..]

Если ResultSet объект может обнаружить делеции, то ResultSet метод rowDeleted возвращает истину, если текущая строка была удалена и ложным, когда он не имеет. Однако rowDeleted также возвращает false, если объект ResultSet не может обнаружить удаления. Можно вызвать метод DatabaseMetaData.deletesAreDetected(int type), чтобы определить, может ли объект ResultSet указанного типа вызвать метод rowDeleted для обнаружения видимого удаления. Метод deletesAreDetected возвращает false, если строка, удаленная из объекта ResultSet, удаляется из него, а true, если удаленная строка заменена пустой или недопустимой строкой.

Это занимает некоторое чтение между строками (и, глядя на куске кода примера в этом разделе), но это означает, что deletesAreDetectedтолько имеет смысл, если удаления видимы, он усматривает как в удалениях являются visible: либо строка была удалена (false), либо заменена пустой или недопустимой строкой (true).

Так как ownDeletesAreVisible возвращает false, результат deletesAreDetected не имеет смысла в отношении «собственных» удалений (кроме «удаления не обнаружены»); он может иметь смысл в отношении «других» удалений, но я сомневаюсь, что другие удаления видны, когда ваши собственные нет.

+0

Я вижу, что вы имеете в виду, за исключением первой части, когда говорится, что DatabaseMetaData.ownDeletesAreVisible (тип int) возвращает false, если объект ResultSet по-прежнему содержит удаленную строку. В моем сценарии он вернул значение false, что означает, что результаты все еще имели его, не заменяя ничего. Почему тогда удаленная строка больше не была в наборе результатов, когда я распечатал ее снова? –

+0

У меня были и собственныеDeletesAreVisible, и deleteesAreDetected, возвращающие false. В нем говорится: «Если удаленная строка удалена или заменена пустой строкой, метод DatabaseMetaData.ownDeletesAreVisible (тип int) вернет true». Поэтому моя строка не была удалена или заменена. Он также говорит: «Метод removeesAreDetected возвращает false, если из него удалена строка, удаленная из объекта ResultSet». Почему я ошибаюсь? ownDeletesAreVisible сказал, что он не был удален. Это «полемика», которую я пытаюсь понять. –

+0

@imacellone, то я могу только предположить, что либо моя интерпретация неверна, либо используемый вами драйвер неправильно определяет его поведение в DatabaseMetaData. –