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

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

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

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

1回答

4828閲覧

DBから複数レコードを取り出すプログラミングについて

Josh_Jan_J

総合スコア4

Java

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2020/08/29 09:17

編集2020/08/29 10:02

以下のクラスがあります。
・Empクラス
⇨社員ID、社員名、所属フィールドがある
・EmpDAOクラス
⇨DBに接続してSQL文を実行、取得した複数のレコードをリストで返す
・Mainクラス
⇨main()実行、取り出したレコードを表示

多くの場合、EmpDAOのメソッドで、
①SQL文実行、ResultSetに格納
②next()でレコードを一行ずつlistに追加
という処理をすると思います(だいぶ省いてますが)

今回、while文を使って②の処理を行ったのですが、取り出したi行目のレコードを一旦格納するEmp型変数empのオブジェクトを、EmpDAOクラス内のどこで作ったかによって、最終的な表示結果が変わってしまいました。

ケース①
・処理を行うメソッド(searchAllという名前に今回はしました)内の一番最初で行う
結果
・rsに取り出した複数レコードのうち、一番最後の行のレコードが、取り出した行分表示された

例) 001、鈴木、営業
002、高橋、経理
003、田中、企画 が取り出したレコードだとすると、
003、田中、企画
003、田中、企画
003、田中、企画
と表示されてしまった

ケース②
・while(rs.next())内で行う
結果
・取り出したレコードが一行ずつ正しく表示された

何故このように処理が変わってしまうのか、わかる方はどうかご教示下さい!

言語 Java ver.8
環境 eclipse

以下searchAll()メソッドです。

Java

1public List<Emp> searchAll() { 2List<Emp> list = new ArrayList<Emp>(); 3String sql = "SELECT empno, ename, job " 4+ "FROM emp;"; 5 6try(Connection conn = DriverManager.getConnection(*パスを記述しています); 7PreparedStatement pstmt = conn.prepareStatement(sql);) { 8 9ResultSet rs = pstmt.executeQuery(); 10 11while(rs.next()) { 12Emp emp = new Emp(); 13int empno = rs.getInt("empno"); 14String ename = rs.getString("ename"); 15String job = rs.getString("job"); 16 17emp.setEmpno(empno); 18emp.setEname(ename); 19emp.setJob(job); 20 21list.add(emp); 22} 23} catch(SQLException e) { 24e.printStackTrace(); 25} 26return list; 27} //メソッド終了

こんな感じです。
上記は正しく表示された記述です。

ケース①のようになってしまったときは、
Emp emp = new Emp();
を while(rs.next()) の中ではなく、
public List<Emp> searchAll() {
のすぐ下に記述しておりました。

宜しくお願い致します!

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

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

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

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

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

shiena

2020/08/29 09:33

> ②next()でレコードを一行ずつlistに追加 この処理がうまくいく方法といかない方法で違ってるような気がします。ResultSet取得後のにlistに追加する処理とsearchAllのコードを載せられませんか?
m.ts10806

2020/08/29 09:51

一通りコードを提示された方が良いかと思います。
Josh_Jan_J

2020/08/29 09:53

コメント有難うございます! 以下searchAll()メソッドです。 public List<Emp> searchAll() { List<Emp> list = new ArrayList<Emp>(); String sql = "SELECT empno, ename, job " + "FROM emp;"; try(Connection conn = DriverManager.getConnection(*パスを記述しています); PreparedStatement pstmt = conn.prepareStatement(sql);) { ResultSet rs = pstmt.executeQuery(); while(rs.next()) { Emp emp = new Emp(); int empno = rs.getInt("empno"); String ename = rs.getString("ename"); String job = rs.getString("job"); emp.setEmpno(empno); emp.setEname(ename); emp.setJob(job); list.add(emp); } } catch(SQLException e) { e.printStackTrace(); } return list; } //メソッド終了 こんな感じです。 上記は正しく表示された記述です。 ケース①のようになってしまったときは、 Emp emp = new Emp(); を while(rs.next()) の中ではなく、 public List<Emp> searchAll() { のすぐ下に記述しておりました。 宜しくお願い致します!
m.ts10806

2020/08/29 09:54

質問は編集できますので。 こちらに提示されても目につきませんしマークダウンが使えません。
Josh_Jan_J

2020/08/29 09:57

失礼致しました、先程質問本文を編集致しました。ご教示有難うございます!
m.ts10806

2020/08/29 09:59

コードはマークダウンのcode機能を利用してご提示ください。
Josh_Jan_J

2020/08/29 10:03

このような方法があったのですね、有難うございます!
guest

回答1

0

ベストアンサー

ケース①のようになってしまったときは、
Emp emp = new Emp();
を while(rs.next()) の中ではなく、
public List<Emp> searchAll() {
のすぐ下に記述しておりました。

正にこれが原因です。
そのように記述するとlistに追加しているのは同じインスタンスなのでwhileで毎回上書きされて最後にsetした値になります。なのでwhileの中でnew Emp()するとそれぞれ異なったインスタンスになり各ループでsetした値になります。

図解すると以下のようになります。
イメージ説明

投稿2020/08/29 10:12

編集2020/08/29 10:28
shiena

総合スコア1825

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

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

Josh_Jan_J

2020/08/29 10:30 編集

ご回答ありがとうございます! 原因、理解できました。同じオブジェクトでリストを繰り返し作っていたので、一番最後にsetした値が、全リストに反映されてしまったんですね。レコード一つ一つ、別のオブジェクトを作ってあげないとだめなのか... 勉強になりました!
shiena

2020/08/29 10:29

listに追加したものが何なのか分かりやすいように図を追加してみました
Josh_Jan_J

2020/08/29 10:30

図解の追加、有難うございます!とても分かりやすいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問