我有以下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; } }
我正在从数据库中检索数据并将其添加到我的数组列表中,如下所示
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>
这里,
ViewAlbum album = new ViewAlbum(); // ... while (resultSet.next()) { album.setAlbumid(resultSet.getInt("albumid")); // ... allAlbums.add(album); }
您将album所有记录重复使用相同的实例。实例的数据在循环中每次都被覆盖。该列表不包含实例的副本,但包含单个实例的 引用 的副本。您知道,Java是面向对象的。
album
您应该为album每个记录创建一个新实例。将实例移到循环内部。
// ... while (resultSet.next()) { ViewAlbum album = new ViewAlbum(); album.setAlbumid(resultSet.getInt("albumid")); // ... allAlbums.add(album); }
与 具体问题 无关 ,您应该在finally块中关闭JDBC资源,或者在try()try-with- resources语句中打开它们,否则在执行查询或处理结果集期间发生异常时,它们仍会泄漏出去。您还应该将JDBC资源的声明移到方法块内部,否则也会遇到线程安全性问题。最后但并非最不重要的一点是,您应该使用setter方法PreparedStatement在SQL字符串中设置用户控制的变量。如果它们是字符串,那么您将有一个SQL注入攻击孔。
finally
try()
PreparedStatement