質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

16080閲覧

JavaでSQL接続時に例外が発生する

syabon

総合スコア11

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/01/20 13:08

編集2017/01/20 14:29

###前提・実現したいこと
DBに接続して読み書きする際に、このクラスだけで接続から切断までの処理を一括で行いと考えています。
他のクラスから利用する際、connect → sql実行 → close だけのシンプルな処理にしたいのです。
ResultSetがclose後に取得出来ないのは分かるのですが、それを回避する方法が分かりません。
###発生している問題・エラーメッセージ

重大: null java.sql.SQLException: Operation not allowed after ResultSet closed at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:743) at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6301) at dao.DbConnection.main(DbConnection.java:99)

###該当のソースコード(質問後に修正しています。)

Java

1public class DbConnection { 2 private Connection con; 3 private Statement stmt; 4 private ResultSet result; 5 6 private String url = "jdbc:mysql://localhost:3306/database?useSSL=false"; 7 private String drv = "com.mysql.jdbc.Driver"; 8 private String id = "root"; 9 private String pass = ""; 10 11 static{ 12 try { 13 Class.forName("com.mysql.jdbc.Driver"); 14 } catch (ClassNotFoundException ex) { 15 ex.printStackTrace(); 16 } 17 } 18 19 public DbConnection(){ 20 try { 21 con = DriverManager.getConnection(url, id, pass); 22 } catch (SQLException ex) { 23 ex.printStackTrace(); 24 } 25 } 26 27 public ResultSet executeQuery(String sql){ 28 if(con != null){ 29 try{ 30 stmt = con.createStatement(); 31 result = stmt.executeQuery(sql); 32 }catch(SQLException ex){ 33 return null; 34 } 35 } 36 return result; 37 } 38 39 public int executeUpdate(String sql){ 40 int i = 0; 41 if(con != null){ 42 try{ 43 stmt = con.createStatement(); 44 i = stmt.executeUpdate(sql); 45 }catch(SQLException ex){ 46 System.out.print(ex.getLocalizedMessage()); 47 return -1; 48 } 49 } 50 return i; 51 } 52 53 public boolean close(){ 54 try{ 55 stmt.close(); 56 con.close(); 57 }catch(SQLException ex){ 58 ex.printStackTrace(); 59 return false; 60 } 61 return true; 62 } 63 64 public static void main(String[] args){ 65 66 try { 67 DbConnection con = new DbConnection(); 68 Cart cart = new Cart(); 69 ResultSet result = con.executeQuery("SELECT * FROM PRODUCTS"); 70 while(result.next()){ 71 Product p = new Product(result.getInt(1),result.getString(2),result.getString(3),result.getString(4)); 72 cart.addItem(p,10); 73 } 74 con.close(); //StatementとConnectionをクローズ 75 con.result.close(); //ResultSetをクローズ(不要になった時点で閉じる) 76 cart.show(); 77 78 } catch (SQLException ex) { 79 Logger.getLogger(DbConnection.class.getName()).log(Level.SEVERE, null, ex); 80 } 81 } 82}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

例外が発生しているのはcloseのところではなく、mainメソッド内のnext()を呼んでいるところですよね。これは、例外になります。

ResultSetというのは、問い合わせ結果を全部保持しているわけではないと考えてください。だからArrayListみたいなオブジェクトとはちょっと違うのです。
ではどういうオブジェクトなのかというと、DBから順次飛んでくる結果を受け取るバッファです。100件や1000件のデータなら結果は一瞬で取れるでしょうが、DBの仕事は数千万件、数十億件といったデータを扱うこと。そういうデータは取り出そうにも一瞬では取り出せませんし、結果として取り出すために全部メモリに格納しようとしたらメモリが足りません。
だから、DBが結果を出力し始めたらアプリも先頭から順次処理していくということができないといけず、その窓口がResultSetなのです。

ResultSetからデータを読み出す前に窓口であるResultSetを閉じてしまっては、もう読み出せなくて当然です。もしやりたいような「シンプルな」クラスインターフェースにしたいなら、ResultSetからArrayListにデータを全部抜き出してからcloseしてArrayListを返す形にしてみてください。無論、前述のような巨大データには対応できないプログラムになります。

投稿2017/01/20 13:23

yuba

総合スコア5568

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syabon

2017/01/20 14:31

ご回答ありがとうございます。 DbConnection クラスを使う側で閉じるように修正しましたが、これでよいのでしょうか。
yuba

2017/01/20 14:43

良さげに見えます。
syabon

2017/01/20 14:45

ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問