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

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

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

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

Q&A

解決済

2回答

4696閲覧

DBのレコードを配列に格納したら一つのインデックスに複数行レコードが纏めて格納されてしまう

pokemn

総合スコア16

Java

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

0グッド

0クリップ

投稿2019/02/24 09:34

前提・実現したいこと

いつもお世話になっております。
現在、Javaで開発を行っているのですが、下記問題が発生しており困っております。
Dbaccess.javaクラスで1レコードを配列の0番目に2レコードを配列の1番目に格納...という風に動作させたいのですが、
現在では、2レコード目を格納しようとすると1番目に格納されるのですが、0番目のレコードにも追加されてしまいます。
この場合、どうしたら0番目に追加されずに1番目だけに値が入るようになりますでしょうか?
対象行:while(rset.next()) ~ userInfDto.setUserInformationList(list);
■下記、実際の配列の値になります。
※レコードが追加される度にすべてのインデックスに追加されてしまいます。
1レコード(最初):1, aaa ~
2レコード(最初):2, bbb ~
3レコード(最初):3, ccc ~
[[1, aaa, 2018-01-10, 2019-02-20, 1, null, 2, bbb, 2019-10-10, 2019-10-20, 2, null, 3, ccc, 2019-08-10, 2019-09-20, 3, null],
[1, aaa, 2018-01-10, 2019-02-20, 1, null, 2, bbb, 2019-10-10, 2019-10-20, 2, null, 3, ccc, 2019-08-10, 2019-09-20, 3, null],
[1, aaa, 2018-01-10, 2019-02-20, 1, null, 2, bbb, 2019-10-10, 2019-10-20, 2, null, 3, ccc, 2019-08-10, 2019-09-20, 3, null]]

どなたかご教授お願い致します。

■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

java

1public class Dbaccess extends Userinformationdto{ 2 3 DataSource ds; 4 5 public Dbaccess() throws ServletException { 6 try { 7 InitialContext ic = new InitialContext(); 8 ds = (DataSource)ic.lookup("java:/comp/env/jdbc/SQLServer"); 9 10 } catch(Exception e) { 11 12 } 13 } 14 15 public Userinformationdto Confimation(String user, int psw , Userinformationdto userInfDto) { 16 17 Connection con = null; 18 PreparedStatement pstmt = null; 19 ResultSet rset = null; 20 21 try { 22 con = ds.getConnection(); 23 if (user != null && psw != 0) { 24 25 StringBuffer sql = new StringBuffer(); 26 27 sql.append("select user_id, user_name, user_password from user_table where user_name='" + user +"'" + "and user_password=" + psw ); 28 29 // sql文実行準備 30 pstmt = con.prepareStatement(new String(sql)); 31 32 // sql文実行 33 pstmt.execute(); 34 35 // 実行結果を、ResultSetクラスに代入 36 rset = pstmt.executeQuery(); 37 if(rset.next()) { 38 userInfDto.setUser(rset.getString("user_name")); 39 userInfDto.setPsw(rset.getInt("user_password")); 40 System.out.println(getUser()); 41 System.out.println(getPsw()); 42 //StringBuilderの初期化を行います。 43 sql.delete(0, sql.length()); 44 sql.append("select task_number, task_title, task_start_date, task_end_date, task_status, task_description from user_table INNER JOIN user_task_table on user_task_table.user_id='" + rset.getString("user_id") + "'where user_name='" + user +"'" + "and user_password=" + psw); 45 System.out.println(sql); 46 // sql文実行準備 47 pstmt = con.prepareStatement(new String(sql)); 48 // sql文実行 49 pstmt.execute(); 50 //結果格納前に初期化を行います。 51 rset = null; 52 System.out.println(getUser()); 53 System.out.println(getPsw()); 54 // 実行結果を、ResultSetクラスに代入 55 rset = pstmt.executeQuery(); 56 ArrayList arrayList = new ArrayList(); 57 List<ArrayList> list = new ArrayList(); 58 while (rset.next()) { 59 arrayList.add(rset.getInt("task_number")); 60 arrayList.add(rset.getString("task_title")); 61 arrayList.add(rset.getDate("task_start_date")); 62 arrayList.add(rset.getDate("task_end_date")); 63 arrayList.add(rset.getInt("task_status")); 64 arrayList.add(rset.getString("task_description")); 65 list.add(arrayList); 66 } 67 userInfDto.setUserInformationList(list); 68 } 69 } else { 70 return userInfDto; 71 } 72 } catch (SQLException e) { 73 // TODO 自動生成された catch ブロック 74 e.printStackTrace(); 75 } finally { 76 try { 77 if (con != null) { 78 con.close(); 79 } 80 } catch (SQLException e) { 81 // TODO 自動生成された catch ブロック 82 e.printStackTrace(); 83 } 84 } 85 return userInfDto; 86 } 87 88}

試したこと

userInfDto.setUserInformationList(list);をwhile(rset.next())の中に入れて、userInfDto.setUserInformationList(list);に
値を格納後、毎回arraylistを初期化してみたりしたのですが、うまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

ループ内で値を設定しております arrayList が, ループの1回目, 2回目, …で全て同じものを指しております.
list.add(arrayList);
によって list に格納されるのは arrayList への参照ですので, list の全ての要素が同じ arrayList を指すことになっております.

ArrayList arrayList = new ArrayList();

をループの開始直後に実行し, ループ毎に別の ArrayList にして頂く必要がございます.


回答とは関係ありませんが, ご注意頂きたく追記いたします.

SQL の実行におきまして

sql.append("select user_id, user_name, user_password from user_table where user_name='" + user +"'" + "and user_password=" + psw ); pstmt = con.prepareStatement(new String(sql));

のように SQL を Java の文字列として生成するのは危険です.

sql.append("select user_id, user_name, user_password from user_table where user_name=? and user_password=?"); pstmt = con.prepareStatement(sql.toString()); pstmt.setString(1, user); pstmt.setString(2, psw);

のように, パラメータ設定をご利用ください.
SQLインジェクション対策となります.

投稿2019/02/24 11:25

編集2019/02/24 11:43
jimbe

総合スコア12646

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

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

swordone

2019/02/24 13:17

そもそもStringBuffer使っている意味が全くないというね…
pokemn

2019/02/26 12:33

遅くなり申し訳ありません。 無事解決しました。 またお二人のご指摘されている箇所も合わせて修正致します。 まだまだ勉強中の為、お見苦しいソースコードで申し訳ありませんでした。
guest

0

回答はすでに出ていますが、いろいろ突っ込みたくなったので…

try-with-resourcesを使おう(Java8以降)

煩わしいfinallyでのリソースクローズをする必要がなくなります。

java

1// 変更前 2Connection con = null; 3try { 4 con = ds.getConnection(); 5 .... 6} catch (SQLException e) { 7 e.printStackTrace(); 8} finally { 9 try { 10 if (con != null) { 11 con.close(); 12 } 13 } catch (SQLException e) { 14 e.printStackTrace(); 15 } 16} 17 18// 変更後 19try (Connection con = ds.getConnection()) { 20 .... 21} catch (SQLException e) { 22 e.printStackTrace(); 23}

StringBufferの意味全くナシ

jinbeさんの回答のコメントにも書いたけど、StringBufferの意味が全くないです。
ループなんかで繰り返し文字列連結をするなら効果がありますが、この場面では全くその特性が生かされていません。
普通の文字列連結で済みます。
(まあそもそもjinbeさんの回答の通り、SQLインジェクション対策の面では悪手ですが)

java

1// 変更前(もう1か所あるが同じ) 2sql.append("select user_id, user_name, user_password from user_table where user_name='" + user +"'" + "and user_password=" + psw ); 3pstmt = con.prepareStatement(new String(sql)); 4 5// 変更後 6String sql1 = "select user_id, user_name, user_password from user_table where user_name='" + user +"'" + "and user_password=" + psw; 7pstmt = con.prepareStatement(sql1);

Listなどのジェネリクスのない形(raw type)を使わない

これはsetUserInformationListメソッドの仕様にもよる、または影響しますが、ジェネリクスを使わない形は避けましょう。

java

1// 変更前 2ArrayList arrayList = new ArrayList(); 3List<ArrayList> list = new ArrayList(); 4 5// 変更後(ついでに左辺の型やジェネリクスをArrayListからListに変更) 6List<Object> arrayList = new ArrayList<>(); 7List<List<Object>> list = new ArrayList<>();

まあそもそもこの結果格納用クラスでも用意しろよとは思うのですが…

まだあるけどとりあえずこんなところ…

投稿2019/02/24 17:13

swordone

総合スコア20651

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問