2

我有以下代码:

String sql = "SELECT * FROM users WHERE email = " + email;
prestat = DBConnection.prepareStatement(sql);
rs = prestat.executeQuery();
boolean isEmpty = !rs.first();
if (isEmpty) {
  // Special marker for nonexistent user
  return "$null";
} else if (password.equals(rs.getString(2))) {
  String uuid = UUID.randomUUID().toString();
  // Here I want to insert the UUID into the database
}   

考虑到我已经搜索过数据库,我想知道是否有一种方法可以获得行号/位置,并使用它来更新 UUID 列,从而防止另一个数据库搜索。

4

2 回答 2

3

目前尚不清楚您要在这里做什么,而且您似乎并不真正了解发生了什么。例如,当使用准备好的语句时,不会使用两个连接的字符串来提供它,而是:

PreparedStatement stmt =
        conn.prepareStatement("SELECT * FROM foo WHERE bar = ?");
stmt.setString(1, "Hello World!");

那么,如果你真的想避免双重搜索,你可以简单地假设一个乐观的观点:

UPDATE users SET uuid = ? WHERE email = ? AND password = ?

顺便说一句,确保电子邮件是唯一的。另外,也许您已经这样做了,但不要在数据库中保存明文密码。改用加密哈希,然后加盐。

由于您指定后端是 Apache Derby,也许本指南可以帮助您解决问题(它是 100% Java,但不是真正可移植的,因为不同的后端可能无法实现所有必需的功能)。基本上,您在准备语句时传递了两个标志:

Statement stmt = con.createStatement(
    ResultSet.TYPE_FORWARD_ONLY, 
    ResultSet.CONCUR_UPDATABLE);
ResultSet res = stmt.executeQuery("SELECT * FROM users WHERE email = ?");

然后你有一个ResultSet可更新的游标支持,所以你可以调用:

res.updateString("uuid", uuid);
res.updateRow();

我认为这可以避免额外的搜索,但是我没有测试它,也不能说是否有真正的性能提升。不过,这听起来像是过早的优化。

于 2013-04-06T08:46:24.113 回答
1

好吧,您可以简单地替换

prestat = DBConnection.prepareStatement("SELECT * FROM users WHERE email =" + email);

经过

prestat = DBConnection.prepareStatement("Update users set uuid = '" + uuid + "' WHERE email =" + email);

当然执行。

于 2013-04-06T08:46:02.287 回答