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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

JSP

JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

Java

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

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

3回答

12104閲覧

javaからMysqlへのInsert文実行について

manmos

総合スコア55

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

JSP

JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

Java

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

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

0グッド

1クリップ

投稿2016/03/05 10:30

只今javaの学習の一環でwebアプリケーションの作成を行ってます。
現在javaの勉強として人員管理のwebアプリを作っています。
Mysqlのレコードを→Dao→jspで一覧表示、逆にjspのフォームへ情報を入力し、レコード登録や削除を行うといった物です。
一覧を表示する部分はできたのですがレコードの登録、Insert文の使用方法がいまいち理解できないです。
jspの入力フォームは複数あり、テーブルが二つになるのですがこの場合insert文はどのように行えば良いのでしょうか。
まず現状のコード(insertメソッド)ですが、

public void InsertInformation(String name, String name_hiragana, String enter_date) throws ClassNotFoundException, SQLException { //SQL文 String sql = "INSERT INTO employee_info (name, name_hiragana) values(?, ?)"; String sql2 = "INSERT INTO employee_state (enter_date) values(?)"; /* * DB接続/挿入/終了 */ try { Class.forName("com.mysql.jdbc.Driver"); //ドライバクラスのロード conn = DriverManager.getConnection(url, user, password); //Connectionクラス生成 pstmt = conn.prepareStatement(sql); //PreparedStatementクラス生成 pstmt.setString(1, name); pstmt.setString(2, name_hiragana); pstmt.executeUpdate(); pstmt = conn.prepareStatement(sql2); pstmt.setString(1, enter_date); pstmt.executeUpdate(); //INSERT文を実行 conn.close(); } catch(SQLException e){ } catch (ClassNotFoundException e) { } finally { //終了処理 //PreparedStatement終了 if(pstmt != null) { try { pstmt.close(); } catch (SQLException e) { } pstmt = null; } //Connection終了 if(conn != null) { try { conn.close(); } catch (SQLException e) { } conn = null; } } }

といったものになります。
jsp側で入力した値を変数に格納することはできていて、insertも一つ目のテーブルに対してはうまくいっています。
二つ目のsql2がうまくいかないのは何故なのでしょうか。
わかる方がいればご享受頂ければと思います。
どうぞ宜しくお願い致します。

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

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

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

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

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

umed0025

2016/03/05 10:50 編集

「} catch (SQLException e) {」の部分に「e.printStackTrace();」を追加して実行し、 エラーログに出ている情報があるとわかりやすくなると思います。。
manmos

2016/03/05 16:50

コードに追記をして再度試してみるとエラー画面が表示されました。 こういった試し方をしたことがないので勝手がわからないのですが」エラーログというのはコンソールに表示された情報で良いのでしょうか。 一応、次の通りです。 重大: サーブレット servlet.List のServlet.service()が例外を投げました java.lang.NullPointerException at Dao.listDao.convertAge(listDao.java:205) at Dao.listDao.findAll(listDao.java:62) at servlet.List.doGet(List.java:32) at javax.servlet.http.HttpServlet.service(HttpServlet.java:624) at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) 今までろくにコンソールを見てなかったので見方をほとんど理解できていないです・・・これで良いのでしょうか。
guest

回答3

0

  1. 例外の分析

上のSQLの実行結果とこの例外が直接関係していません。
java.lang.NullPointerException at Dao.listDao.convertAge(listDao.java:205) at

insertInformation()メソッド実行後に発生した例外のようです。

  1. 考えられるシナリオ。

AUTO COMMITがTRUEであると仮定します。これはMySQLの設定を確認してください。
・最初のINSERTが成功してfooにレコードが挿入される。自動的にCOMMITされる。
・二番目のINSERTに失敗。(原因は、日付フォーマットなのか、SQLなのかは不明です)
SQLExcetionが発生するが、例外処理が記述されていないため何もせず、finallyを実行して退出する。

  1. 原因特定

以下のe.printStackTrace()文を追加してください。

} catch(SQLException e){ e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }
  1. よくない点

例外処理は必ず記述しましょう。発生した例外を無視してはいけません。

AUTO COMMITを明示的にfalseにすべき。
Connection.commit(), Connection.rollback()を明に記述すること。
Connectionにtry-with-resourceを適用してはいけません。rollback()できなくなります。
Connectionはtry-finallyの中で閉じてください。

PreparedStatementを閉じるのならそれぞれ閉じること。
PreparedStatementには、try-with-resourceを使っても良いでしょう。

Class.forNameは一度だけ呼ばれれば良いので、別の箇所に記述しましょう。
できれば、WEBコンテナにデータソースを定義してください。

投稿2016/09/11 11:38

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

KiyoshiMotoki

2016/09/11 13:07 編集

vornan19様 おおむね良い回答ですが、1点だけ補足させてください。 JDK1.6 以降は、Class.forName の記述は不要ですよ。 http://docs.oracle.com/javase/jp/6/api/ > アプリケーションでは、Class.forName() を使用して JDBC ドライバを明示的にロードする必要がなくなりました。
退会済みユーザー

退会済みユーザー

2016/09/13 03:05

ありがとうございます。忘れていました。 > JDK1.6 以降は、Class.forName の記述は不要ですよ。 JDBCのバージョンの違いについて補足しておきます。  JDBC 3.0 以前、Class.forName()が必要。  JDBC 4.0 以降、Class.forName()は必要ないが、あっても問題ない(後方互換)。 これはひとつのトピックになると思います。 ここでの教訓  回答者は、バージョンを意識してできるだけ正確に応える。  質問者は、質問の説明に、実行環境やバージョンをできるだけ明記する。 ということでしょうか。KiyoshiMotokiさんありがとうございました。
guest

0

「java.lang.NullPointerException at Dao.listDao.convertAge(listDao.java:205)」でNullPointerException がでていますのでSQL文とは関係なさそうですね。

念のため、同一コネクションでPraperedStatementを2つ使う検証サンプルを作ってみましたが特にエラーはでませんでした。

java

1package sandbox; 2 3import java.sql.Connection; 4import java.sql.DriverManager; 5import java.sql.PreparedStatement; 6import java.sql.SQLException; 7 8public class SQLSample { 9 private static final String sql1 = "INSERT INTO foo (No,Value)VALUES (?,?)"; 10 private static final String sql2 = "INSERT INTO bar (No,Value)VALUES (?,?)"; 11 12 public void mySqlMultiTableInsertSample() { 13 14 try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sandbox?useSSL=true", 15 "user", "passwrod")) { 16 connection.setAutoCommit(false); 17 PreparedStatement ps1 = null; 18 try { 19 ps1 = connection.prepareStatement(sql1); 20 ps1.setInt(1, 1); 21 ps1.setString(2, "value1"); 22 ps1.executeUpdate(); 23 } catch (SQLException e) { 24 connection.rollback(); 25 throw e; 26 } finally { 27 try { 28 if (ps1 != null) { 29 ps1.close(); 30 } 31 } catch (SQLException e) { 32 e.printStackTrace(); 33 } 34 } 35 PreparedStatement ps2 = null; 36 try { 37 ps2 = connection.prepareStatement(sql2); 38 ps2.setInt(1, 2); 39 ps2.setString(2, "value2"); 40 ps2.executeUpdate(); 41 } catch (SQLException e) { 42 connection.rollback(); 43 throw e; 44 } finally { 45 try { 46 if (ps2 != null) { 47 ps2.close(); 48 } 49 } catch (SQLException e) { 50 e.printStackTrace(); 51 } 52 } 53 connection.commit(); 54 } catch (SQLException e) { 55 e.printStackTrace(); 56 } 57 } 58}

テーブル情報

mysql> show columns from foo; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | No | int(11) | NO | PRI | NULL | | | Value | text | YES | | NULL | | +-------+---------+------+-----+---------+-------+ mysql> show columns from bar; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | No | int(11) | NO | PRI | NULL | | | Value | varchar(45) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+

eclipseを使っているのであれば、JUnit使ってInsertInformationを呼び出してみるのもよいかもしれません。

eclipse+JUnit関連の参考資料
http://qiita.com/takehiro224/items/a5d4265c4a1b36b0919c

追記:
同じインスタスでないので動くのでは?とコメントで別の方から突っ込みを受けたのですが、
PreparedStatementについては元々同じインスタンスではないですよ。
以下のコードでも正常に動きます。
コネクションの処理や、例外の処理についてお勧めではないです。

package sandbox; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class SQLSample2 { private static final String sql1 = "INSERT INTO foo (No,Value)VALUES (?,?)"; private static final String sql2 = "INSERT INTO bar (No,Value)VALUES (?,?)"; public void mySqlMultiTableInsertSample() { try { Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sandbox?useSSL=true", "root", "admin"); PreparedStatement ps1 = connection.prepareStatement(sql1); ps1.setInt(1, 1); ps1.setString(2, "value1"); ps1.executeUpdate(); ps1 = connection.prepareStatement(sql2); ps1.setInt(1, 2); ps1.setString(2, "value2"); ps1.executeUpdate(); connection.close(); } catch (Exception e) { throw new RuntimeException(e); } } }

投稿2016/03/05 17:30

編集2016/03/06 09:44
umed0025

総合スコア851

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

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

退会済みユーザー

退会済みユーザー

2016/03/05 23:23

インスタンスをわけていれば、問題が出ないのは当然です。 同じインスタンスで2回使用するのが問題なのです。
guest

0

prepareStatement は、1回SQLを登録し、複数回同じSQLで、値を変えて実行するのために
あるため、2つのsqlに使用できない。

prepareStatement ではなく、Statement に変更するとどうでしょうか

投稿2016/03/05 11:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問