現在エラーが発生していますが、
Java.sql.SQLException: Method 'executeQuery(String)' not allowed on prepared statement.
私が使っているので
PreparedStatement stmt = conn.prepareStatement(sql);
そしてまた持っていた
ResultSet rs = stmt.executeQuery(sql);
私のコードで。
ResultSet行を削除する必要がありますが、次のコードを処理する必要があります。
if (rs.next()) {
messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("login.successful"));
request.getSession(true).setAttribute("USERNAME", rs.getString("USERNAME"));
request.getSession(true).setAttribute("BALANCE", rs.getString("BALANCE"));
request.setAttribute("msg", "Logged in successfully");
私は完全に何を理解しているのかわかりません
if (rs.next())
します。誰かがこのコードを私に説明できますか?そのことをよく理解していれば、rsに使用されているロジックでPreparedStatementの結果を使用して対処する方法について、より良いアイデアが得られると思います。また、そのロジックの変更に対処するための支援もいただければ幸いです。
そのSQLException
の具体的な問題については、
_ResultSet rs = stmt.executeQuery(sql);
_
沿って
_ResultSet rs = stmt.executeQuery();
_
PreparedStatement
ではなく Statement
サブクラスを使用しているためです。 PreparedStatement
を使用する場合、SQL文字列はすでにConnection#prepareStatement()
に渡されています。パラメータを設定し、SQL文字列を再渡さずにexecuteQuery()
メソッドを直接呼び出すだけです。
rs.next()
に関する具体的な質問については、データベースからの結果セットの次の行にカーソルを移動し、行がある場合はtrue
を返し、それ以外の場合はfalse
を返します。 。 if
ステートメントと組み合わせて(while
の代わりに)、これは、プログラマーが1行のみ、つまり最初の行のみを期待または関心していることを意味します。
next()
は、カーソルをresultset
の現在の位置から1行前に移動します。したがって、if(rs.next())
は、次の行がnull
でない場合(存在する場合)、Go Ahead。
さて、あなたの問題、
_ResultSet rs = stmt.executeQuery(sql); //This is wrong
^
_
executeQuery(String) は、sql-queryを文字列として使用する場合に使用されることに注意してください。
一方、 PreparedStatement を使用する場合は、このPreparedStatement
オブジェクトでSQLクエリを実行し、生成されたResultSet
オブジェクトを返す executeQuery() を使用しますクエリによって。
ソリューション:
使用:ResultSet rs = stmt.executeQuery();
Java 6を使用しており、使用しているResultSetが_Java.sql.ResultSet
_であると想定しています。
ResultSet.next()メソッドのJavaDoc の状態:
カーソルを現在の位置から1行前に移動します。 ResultSetカーソルは最初、最初の行の前に配置されます。次のメソッドの最初の呼び出しは、最初の行を現在の行にします。 2番目の呼び出しでは、2番目の行が現在の行になり、以下同様に続きます。
Nextメソッドの呼び出しがfalseを返すと、カーソルは最後の行の後に配置されます。現在の行を必要とするResultSetメソッドを呼び出すと、SQLExceptionがスローされます。
したがって、if(rs.next(){ //do something }
は、「結果セットにまだ結果がある場合は、次の結果に移動して何かを行う」ことを意味します。
BalusCが指摘したように 、置き換える必要があります
_ResultSet rs = stmt.executeQuery(sql);
_
と
_ResultSet rs = stmt.executeQuery();
_
前の行のステートメントで使用するSQLをすでに設定しているため
_PreparedStatement stmt = conn.prepareStatement(sql);
_
PreparedStatement
を使用していない場合は、ResultSet rs = stmt.executeQuery(sql);
が機能します。
next()
メソッド(公式ドキュメント here )は、結果行セットのポインタを次の行に移動します(可能な場合)。とにかく、これは公式のドキュメントからも読むことができます:
カーソルを現在の位置から1行下に移動します。
このメソッドは、別の行がある場合はtrueを返し、それ以外の場合はfalseを返します。
写真を見てください、それはクエリselect *から従業員の結果セットです
resultSetクラスのnext()メソッドは、返された結果セットの次の行(例ではrs)にカーソルを移動するのに役立ちます。
:)
Result Setはインターフェースであるため、JDBC呼び出しを介してResultSetへの参照を取得すると、ResultSetインターフェースを実装するクラスのインスタンスを取得します。このクラスは、すべてのResultSetメソッドの具体的な実装を提供します。
インターフェイスは、インターフェイスから実装を分離するために使用されます。これにより、汎用アルゴリズムの作成とオブジェクト作成の抽象化が可能になります。たとえば、異なるデータベース用のJDBCドライバーは異なるResultSet実装を返しますが、異なるドライバーで動作するようにコードを変更する必要はありません。
要するに、ResultSetに結果が含まれている場合、レコードセットがある場合はrs.nextを使用するとtrueが返され、それ以外の場合はfalseが返されます。
まず、書く必要はありません
ResultSet rs = stmt.executeQuery(sql);
書くだけ
ResultSet rs = stmt.executeQuery();
上記の構文は、PreparedStatementではなく、ステートメントに使用されます。
次に、rs.next()は、結果セットに値が含まれているかどうかをチェックします。最初はBEFORE FIRST Positionにあるため、ブール値を返し、カーソルを結果セットの最初の値に移動します。したがって、結果セットの最初の値にアクセスする場合は、rs.next()を記述する必要があります。