• ベストアンサー

DBに接続しブラウザ上に検索結果が全て表示されるServlet

首記の件ですが、コーティングしてコンパイルしても NullPointerExceptionがでてしまいます。 このServletはDB接続クラスと実行Servletにわかれていてます。 原因はDB接続クラスにレコードをカウントするメソッドが あるのですが、そこでNullPointerExceptionが発生して その他に影響を及ぼしているみたいです。 ・・・とまぁ、ここまで理解できたのですが行き詰まって しましましたのでご教授いただけると幸いです。 以下に問題のコードとエラー内容を記述します。 --接続クラス-- (略) private int count() throws SQLException { // 桁数 int rec = 0; // SQL文実行 rs = st.executeQuery("SELECT * FROM TESTTABLE1"); // カウント while(rs.next()) { rec++; } return rec; } } --エラーメッセージ-- java.lang.NullPointerException at DB.count(DB.java:146) at DB.select(DB.java:117) at SELECT.doGet(SELECT.java:73)

質問者が選んだベストアンサー

  • ベストアンサー
  • Bonjin
  • ベストアンサー率43% (418/971)
回答No.4

#2です。 rs.next()を書き忘れましたw >そこでrecにカウント数が入った後にrs.next()を追加してみたのですがダメでした。 何か勘違いしているようですので、ここはちゃんと押さえておきましょう。ResultSetを取得した直後はResultSetは何も指していません。レコードが戻らない時(指定されたレコードがない時など)もあるからです。なので、値を取り出す前にrs.next()をしてあげなければなりません。 ResultSetのnextメソッドは次のレコードが無ければfalseを返し、あれば次のレコードに移ってtrueを返します。JavaDocに書いてあるので読んだ方がいいでしょう。また、DB処理のサンプルはWeb上にたくさんあるので色々見てみるのも勉強になります。 rs = st.executeQuery("SELECT COUNT(*) AS CNT FROM TESTTABLE1"); rs.next(); rec = rs.getInt("CNT");

noname#262515
質問者

お礼

そうでした。。。 next()メソッドはtrueの時に1行下にカーソルを 移動させるから値を取り出した後じゃ遅いのですね。 実行してみたらちゃんと動きました。すみません。 Servletを始めて2週間ぐらい経ちますがなかなか 難しいですね。 NullPointerExceptionの方ですが今までメソッド外で 「Statement st = null;」でオブジェクトを 宣言してたのですがメソッド内で宣言すればNullは なくなると思って下記のコードに直してみましたが ダメでした。if文を使ってnullの場合とそうでない場合を 条件分岐させた方が良いのでしょうか? public int count() throws SQLException { // 桁数 int rec = 0; // SQL実行準備 Statement st = con.createStatement(); // SQL文実行 ResultSet rs = st.executeQuery("SELECT COUNT (*) AS CNT FROM TESTTABLE1"); // カウント while(rs.next()) rec = rs.getInt("CNT"); rs.close(); st.close(); return rec; }

その他の回答 (3)

  • argi
  • ベストアンサー率27% (5/18)
回答No.3

Bonjinさんと基本的に同じで、Statementがnullなのだと思います。 ConnectionからStatementを取得している箇所かConnectionを生成している箇所に問題があると思われるので、参照URLと比較して参考にしてみてください。 蛇足ですが、SQL実行の部分をtry~catchで括ってfinallyでcloseするのが一般的かつ安全だと思われます。

参考URL:
http://www.hellohiro.com/jdbc.htm
noname#262515
質問者

お礼

ありがとうございます。 参考URL見ました。 これ以外にDB接続して全件取得するJavaアプリを 作成したのですが問題なく出来ました。 Statementのオブジェクトを宣言したときに 一緒にConnectionインターフェイスの createStatement()メソッドを設定してNullを 回避しようと試みたのですが。。。ダメっぽいです。 #4のお礼本文のコードがそれにあたります。

  • Bonjin
  • ベストアンサー率43% (418/971)
回答No.2

#1です。 ただのアドバイスですが、レコード数を数えるだけならSQLのCOUNT関数を利用した方が速いしコンピュータに優しいです。この場合、レコードの数だけメモリを消費しているので無駄なリソースを消費しています。 あと、レコードセットは確実に閉じるようにした方がいいと思います。 rs = st.executeQuery("SELECT COUNT(*) AS CNT FROM TESTTABLE1"); rec = rs.getInt("CNT"); rs.close();

noname#262515
質問者

お礼

ありがとうございます。 SQL文をBonjinさんが教えてくれたCOUNT関数を 利用してやってみる事にしました。 それで、Servlertで実行する前にJavaアプリの方で DB接続の実行クラスを作ってしてみたら「カーソルの 状態が向こうです。」とSQLExceptionがでました。 そこでrecにカウント数が入った後にrs.next()を 追加してみたのですがダメでした。 カウント数が入った後に行を移動するように したつもりだったのですが。。。なぜでしょうか? すみませんが教えてください。

  • Bonjin
  • ベストアンサー率43% (418/971)
回答No.1

NullPointerExceptionは基本中の基本です。何かがnullだから発生しているという簡単な理由です。何がnullなのかは単に出力するだけで判断することができます。というかデバッグの基本は出力することです。 話を戻して・・・ このソースの中でnullになり得るのはrsとstだけです。 しかし、StatementのexecuteQueryメソッドの戻り値は「nullにならない」とJavaDocに書かれているのでstがnullであると考えて間違いないでしょう。 stはこのcountメソッド内で取得していないようなので問題は他にありそうです。 しかし、stがnullの時の処理も入れておいた方がいいでしょう。

関連するQ&A