java - DatabaseMetaData.ownDeletesAreVisible 与 DatabaseMetaData.deletesAreDetected 争议

标签 java mysql jdbc database-metadata

我将 JDBC 与 mysql-connector-java-6.0.2.jar 一起使用,并且除非我做错了什么,否则我认为 DatabaseMetaData.ownDeletesAreVisible 和 DatabaseMetaData.deletesAreDetected 实现在某种程度上彼此之间表现不一致。

以下是 JDBC 规范中关于 ownDeletesAreVisible 的规定:

"...如果删除的行被删除或被空行替换,DatabaseMetaData.ownDeletesAreVisible(int type) 方法将返回 true。如果 ResultSet 对象仍然包含删除的行,则返回 false,这意味着删除对于给定类型的 ResultSet 对象的更改不可见......

关于deletesAreDetected:

...如果从 ResultSet 对象中删除的行被删除,则该方法将返回 false;如果删除的行被空行或无效行替换,则该方法将返回 true...

我将输出添加为注释:

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();
        }
}

最佳答案

这并不矛盾,JDBC 4.2 specification ,第 15.2.4.2 节说(强调我的):

After the method deleteRow has been called, the current row is deleted in the underlying data source. This deletion is visible as a change in the open ResultSet object if the row is either removed or replaced by an empty or invalid row.

If the deleted row is removed or replaced by an empty row, the method DatabaseMetaData.ownDeletesAreVisible(int type) will return true. It returns false if the ResultSet object still contains the deleted row, which means that the deletion is not visible as a change to ResultSet objects of the given type.

[..]

If a ResultSet object can detect deletions, the ResultSet method rowDeleted returns true when the current row has been deleted and false when it has not. However, rowDeleted also returns false if the ResultSet object cannot detect deletions. The method DatabaseMetaData.deletesAreDetected(int type) can be called to see whether a ResultSet object of the specified type can call the method rowDeleted to detect a deletion that is visible. The method deletesAreDetected returns false if a row deleted from the ResultSet object is removed from it and true if the deleted row is replaced by an empty or invalid row.

这需要一些字里行间的阅读(并查看该部分中的示例代码),但这意味着 deletesAreDetected only 在删除可见的情况下才有意义,它识别删除如何可见:行已被删除 (false),或者替换为空行或无效行 (true )。

因此,由于 ownDeletesAreVisible 返回 falsedeletesAreDetected 的结果对于“自己的”删除没有任何意义(除了“deletes are”)没有检测到');它可能对“其他”删除有意义,但我怀疑当您自己的删除不可见时其他删除是否可见。

关于java - DatabaseMetaData.ownDeletesAreVisible 与 DatabaseMetaData.deletesAreDetected 争议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38214241/

相关文章:

mysql - 如何编辑grails列?

java - 两个应用程序使用 JDBC 连接到 mysql 数据库 : one works,,另一个给出 "The Network Adapter could not establish the connection"

java - Java 预准备语句的 Oracle 错误 "SQL command not properly ended"(ORA-00933)

java - 正则表达式允许字符模式但不允许来自该模式的单个字符

mysql - 尽管授予特权,但 mysql 访问仍被拒绝

mysql - 在 MySQL 中,BIT 列是否适合存储 5、6 或 7 字节整数?

java - 在 MySQL 中同时从不同客户端以同一用户身份登录是否安全?

java - 更改 Wicket 中提交按钮的文本字段

java - Lambda Metafactory 变量捕获

java - java中的文本文件到数组