我有以下代码:
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列,从而阻止了另一个数据库搜索。
答案 0 :(得分:3)
目前尚不清楚你在这里要做什么,而且你似乎并不了解发生了什么。例如,当使用预准备语句时,不会使用两个连接字符串来提供它,而是使用:
PreparedStatement stmt =
conn.prepareStatement("SELECT * FROM foo WHERE bar = ?");
stmt.setString(1, "Hello World!");
然后,如果你真的想避免双重搜索,你可以简单地假设一个乐观的观点:
UPDATE users SET uuid = ? WHERE email = ? AND password = ?
顺便说一下,确保电子邮件是唯一的。此外,也许您已经这样做了,但不要在db中保存明文密码。请使用加密哈希,并加盐。
由于您指定后端是Apache Derby,因此this guide可以帮助您解决问题(它是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();
我认为可以避免额外的搜索,但我没有测试它,也不能说是否有真正的性能提升。听起来像过早的优化。
答案 1 :(得分:1)
你可以简单地替换
prestat = DBConnection.prepareStatement("SELECT * FROM users WHERE email =" + email);
通过
prestat = DBConnection.prepareStatement("Update users set uuid = '" + uuid + "' WHERE email =" + email);
当然是执行。