如何在不发出额外查询的情况下更新刚刚检索到的记录?
Posted
技术标签:
【中文标题】如何在不发出额外查询的情况下更新刚刚检索到的记录?【英文标题】:How do I update just retrieved records without issuing an additional query? 【发布时间】:2013-04-06 08:35:16 【问题描述】:我有以下代码:
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 列,从而防止再次搜索数据库。
【问题讨论】:
我正在使用 Apache Derby。 【参考方案1】:目前尚不清楚您要在这里做什么,而且您似乎并不真正了解发生了什么。例如,当使用准备好的语句时,不会使用两个连接的字符串来提供它,而是这样做:
PreparedStatement stmt =
conn.prepareStatement("SELECT * FROM foo WHERE bar = ?");
stmt.setString(1, "Hello World!");
那么,如果你真的想避免双重搜索,你可以简单地假设一个乐观的观点:
UPDATE users SET uuid = ? WHERE email = ? AND password = ?
顺便说一句,确保电子邮件是唯一的。另外,也许您已经这样做了,但不要在数据库中保存明文密码。改用加密哈希,然后加盐。
由于您指定您的后端是 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();
我认为这可能可以避免额外的搜索,但是我没有对其进行测试,也不能说是否有真正的性能提升。不过,这听起来像是过早的优化。
【讨论】:
我才刚刚开始开发。将很快添加散列。而关于stmt.setString(),有什么性能差异吗?关于双重搜索,我不明白更新将如何阻止第二次搜索。我的问题是,鉴于我已经进行了第一次搜索,我该如何避免第二次搜索。由于其他原因,我需要第一次搜索。 第一次搜索时不要使用SELECT
。只有UPDATE
,因为WHERE
子句中的条件是您的两个if
块的SQL 等价物。
根据实现的不同,可能会有性能优势,但准备好的语句的主要用途是增强您的应用程序以防止格式错误(或恶意)输入
如果我这样做,我如何区分电子邮件错误和密码错误?如果用户根本不存在怎么办?
如果没有更大的上下文,我不能说这是否相关,或者您是否可以通过简单地说明电子邮件或密码不匹配来确定【参考方案2】:
你可以简单地替换
prestat = DBConnection.prepareStatement("SELECT * FROM users WHERE email =" + email);
通过
prestat = DBConnection.prepareStatement("Update users set uuid = '" + uuid + "' WHERE email =" + email);
当然还有执行。
【讨论】:
啊。对不起。我的错。我应该删除该声明。我知道这是错的。这就是我发表评论的原因。以上是关于如何在不发出额外查询的情况下更新刚刚检索到的记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不停机的情况下更新和 ECS 服务添加一个额外的负载平衡服务与之对话?
Django ORM:在不执行 N+1 查询的情况下检索帖子和最新评论