1

私は次のJavaクラスを持っています

package com.picvik.model;

import java.util.Date;

public class ViewAlbum {

private Integer albumid;
private String albumname;
private String description;
private String location;
private Date date;
private Integer uid;

public Integer getAlbumid() {
    return albumid;
}
public void setAlbumid(Integer albumid) {
    this.albumid = albumid;
}
public String getAlbumname() {
    return albumname;
}
public void setAlbumname(String albumname) {
    this.albumname = albumname;
}
public String getDescription() {
    return description;
}
public void setDescription(String description) {
    this.description = description;
}
public String getLocation() {
    return location;
}
public void setLocation(String location) {
    this.location = location;
}
public Date getDate() {
    return date;
}
public void setDate(Date date) {
    this.date = date;
}
public Integer getUid() {
    return uid;
}
public void setUid(Integer uid) {
    this.uid = uid;
}

}

私はdbからデータを取得し、このように配列リストに追加しています

public ArrayList getAllAlbums(Integer uid) {
    ViewAlbum album = new  ViewAlbum();
    ArrayList<ViewAlbum>allAlbums = new ArrayList<ViewAlbum>();
    try {
        String qstring = "SELECT albumid, albumname, description, location," +
                " date, uid FROM picvik_picture_album WHERE " +
                "uid = '" + uid + "';";

        System.out.println(qstring);
        connection = com.picvik.util.MySqlConnection.getInstance().getConnection();
        ptmt = connection.prepareStatement(qstring);
        resultSet = ptmt.executeQuery();
        while(resultSet.next()) {
            //System.out.println(resultSet.getString("albumname"));
            album.setAlbumid(resultSet.getInt("albumid"));
            album.setAlbumname(resultSet.getString("albumname"));
            album.setDescription(resultSet.getString("description"));
            album.setLocation(resultSet.getString("location"));
            album.setDate(resultSet.getDate("date"));
            album.setUid(resultSet.getInt("uid"));
            allAlbums.add(album);
        }

        resultSet.close();
        ptmt.close();
        connection.close();


    } catch (Exception e) {
        e.printStackTrace();
    }   
    return allAlbums;
}

しかし、配列リストに格納されている値を出力しようとすると。それは常に私に最後に挿入されたレコードを与えます。

<div class="row">
                <div class="span10">
                    <s:iterator value="allAlbums">
                        <s:property value="albumname"/>
                    </s:iterator>   
                </div>
            </div>
4

2 に答える 2

14

ここ、

ViewAlbum album = new ViewAlbum();
// ...

while (resultSet.next()) {
    album.setAlbumid(resultSet.getInt("albumid"));
    // ...
    allAlbums.add(album);
}

すべてのレコードでまったく同じalbumインスタンスを再利用しています。インスタンスのデータは、ループ内で毎回オーバーライドされます。リストにはインスタンスのコピーは含まれていませんが、単一のインスタンスへの参照のコピーが含まれています。ご存知のとおり、Javaはオブジェクト指向です。

albumレコードごとに新しいインスタンスを作成する必要があります。インスタンス化をループの内側に移動します。

// ...

while (resultSet.next()) {
    ViewAlbum album = new ViewAlbum();
    album.setAlbumid(resultSet.getInt("albumid"));
    // ...
    allAlbums.add(album);
}

参照:


具体的な問題とは関係なく、ブロック内のJDBCリソースを閉じるfinallyか、try-with-resourcesステートメントで開く必要がありますtry()。そうしないと、クエリの実行中または結果セットの処理中に例外が発生した場合でも、JDBCリソースがリークします。また、JDBCリソースの宣言をメソッドブロック内に移動する必要があります。そうしないと、スレッドセーフの問題も発生します。PreparedStatement最後になりましたが、SQL文字列にユーザー制御変数を設定するには、のsetterメソッドを使用する必要があります。それらが文字列の場合、SQLインジェクション攻撃の穴があります。

参照:

于 2013-01-01T04:59:58.590 に答える
1

ViewAlbumのインスタンスは1つだけで、ループ全体でその1つのインスタンスのみで再生(値の設定)しています。したがって、ループの完了後、N(結果セットのサイズ)のArrayListに挿入されるオブジェクトは1つだけです。

于 2013-01-01T05:18:47.633 に答える