Java 选择";如需更新,请参阅“;使用JDBC?

Java 选择";如需更新,请参阅“;使用JDBC?,java,postgresql,jdbc,select-for-update,Java,Postgresql,Jdbc,Select For Update,我想使用JDBC在Java中为update创建一个select语句,但不确定该如何实现 如果您不熟悉for update,可以在此处阅读 例如,我有以下select语句 我的选择语句 select email from email_accounts where already_linked = false order by random() limit 1 UPDATE email_accounts set already_linked = true, account_link_timest

我想使用JDBC在Java中为update创建一个
select语句,但不确定该如何实现

如果您不熟悉for update,可以在此处阅读

例如,我有以下select语句

我的选择语句

select email from email_accounts where already_linked = false order by random() limit 1
UPDATE email_accounts set already_linked = true, account_link_timestamp = now() where email = ?
我的最新声明

select email from email_accounts where already_linked = false order by random() limit 1
UPDATE email_accounts set already_linked = true, account_link_timestamp = now() where email = ?

在Java中使用JDBC时如何使用
进行更新

首先将
用于更新
添加到您的选择(以及您想要更新的其他列),然后更新它们。此外,如注释中所述,请确保
getConnection
在不自动提交的情况下返回
Connection
。您需要设置一个
语句
类型以进行滚动和
CONCUR\u updateable
。大概

String[] colNames = { "email", "already_linked", "account_link_timestamp" };
String query = "select " + Stream.of(colNames).collect(Collectors.joining(", "))
        + "from email_accounts where already_linked = false for update";
try (Connection conn = getConnection(); // Make sure conn.setAutoCommit(false);
        Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
                ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stmt.executeQuery(query)) {
    while (rs.next()) {
        // Get the current values, if you need them.
        String email = rs.getString(colNames[0]);
        boolean linked = rs.getBoolean(colNames[1]);
        Timestamp time = rs.getTimestamp(colNames[2]);
        // ...
        rs.updateBoolean(colNames[1], true);
        rs.updateTimestamp(colNames[2], //
                new Timestamp(System.currentTimeMillis()));
        rs.updateRow();
    }
} catch (SQLException e) {
    e.printStackTrace();
}

首先将更新的
添加到所选内容(以及要更新的其他列),然后更新它们。此外,如注释中所述,请确保
getConnection
在不自动提交的情况下返回
Connection
。您需要设置一个
语句
类型以进行滚动和
CONCUR\u updateable
。大概

String[] colNames = { "email", "already_linked", "account_link_timestamp" };
String query = "select " + Stream.of(colNames).collect(Collectors.joining(", "))
        + "from email_accounts where already_linked = false for update";
try (Connection conn = getConnection(); // Make sure conn.setAutoCommit(false);
        Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
                ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stmt.executeQuery(query)) {
    while (rs.next()) {
        // Get the current values, if you need them.
        String email = rs.getString(colNames[0]);
        boolean linked = rs.getBoolean(colNames[1]);
        Timestamp time = rs.getTimestamp(colNames[2]);
        // ...
        rs.updateBoolean(colNames[1], true);
        rs.updateTimestamp(colNames[2], //
                new Timestamp(System.currentTimeMillis()));
        rs.updateRow();
    }
} catch (SQLException e) {
    e.printStackTrace();
}

conn.setAutoCommit=false
对于更新
锁有效的
来说是必要的,还是无关紧要的?另外,
createStatement
是否需要使用
ResultSet调用。CONCUR\u updateable
所以
updateRow
将起作用?@GordThompson很好的捕获,谢谢。是 啊晚餐时间到了,我有点匆忙。
conn.setAutoCommit(false)在while循环的正上方就可以了?您可能需要在
选择中包含主键列,以使结果集可通过JDBC更新,即将其添加到
colNames
。更新
锁的
是否需要
conn.setAutoCommit=false
,或者这不重要,
createStatement
是否需要使用
ResultSet.CONCUR\u updateable
调用,这样
updateRow
就可以工作了?@GordThompson很好,谢谢。是 啊晚餐时间到了,我有点匆忙。
conn.setAutoCommit(false)在while循环的正上方就可以了?您可能需要在
选择中包含主键列
,以使结果集可通过JDBC更新,即将其添加到
colNames