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 列を更新し、別の DB 検索を防ぐ方法があるかどうか疑問に思っています。

4

2 に答える 2

3

ここで何をしようとしているのかが明確ではなく、何が起こっているのか理解していないようです。たとえば、準備されたステートメントを使用する場合、2 つの連結された文字列をフィードするのではなく、次のようにします。

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 ですが、バックエンドが異なると必要なすべての機能が実装されていない可能性があるため、完全に移植可能ではありません)。基本的に、ステートメントを準備するときに 2 つのフラグを渡します。

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 に答える