Java期末论文项目:如何用ArrayList列出用户的互粉列表?
问题分析与修正方案
核心逻辑错误
你的第二个PreparedStatement逻辑完全偏离了互粉需求:它查询的是当前用户粉丝的所有关注者,而非筛选出那些同时关注当前用户的粉丝(即互粉用户)。这导致你把粉丝的所有关注对象都加入列表,其中必然包含当前用户自己,所以最终返回的都是你自己的名字。
修正方案(两种思路)
思路1:优化SQL查询(推荐,效率更高)
直接用一条SQL语句找出所有互粉用户,避免嵌套查询和循环,减少数据库交互次数:
public ArrayList<Object[]> listMutualFollowers(int id_user) { ArrayList<Object[]> data = new ArrayList<>(); String sql = "SELECT f1.id_follower " + "FROM followers f1 " + "JOIN followers f2 ON f1.id_follower = f2.id_user " + "WHERE f1.id_user = ? AND f2.id_follower = ?"; try (PreparedStatement ps = connection.prepareStatement(sql)) { ps.setInt(1, id_user); ps.setInt(2, id_user); ResultSet rs = ps.executeQuery(); while (rs.next()) { int mutualId = rs.getInt("id_follower"); data.add(new Object[]{getFollowerName(mutualId)}); } // 不要在此处关闭connection,否则后续无法复用连接 return data; } catch (SQLException e) { JOptionPane.showMessageDialog(null, "listMutualFollowers():" + e.getMessage()); return null; } }
逻辑说明:
- 通过
f1表筛选出所有关注当前用户(id_user)的用户(即你的粉丝) - 关联
f2表,筛选出这些粉丝中同时被当前用户关注的人(即你也关注了他们) - 使用
?占位符避免SQL注入,这是PreparedStatement的正确用法(你原代码直接拼接SQL存在注入风险) - 用try-with-resources自动关闭
PreparedStatement,无需手动调用close(),更安全
思路2:修正原代码的嵌套逻辑
如果坚持用原有嵌套查询方式,需在第二个查询中添加条件,确保当前用户是该粉丝的关注者:
public ArrayList<Object[]> listMutualFollowers(int id_user) { ArrayList<Object[]> data = new ArrayList<>(); try { String sql1 = "SELECT id_follower FROM followers WHERE id_user = ?"; PreparedStatement ps = connection.prepareStatement(sql1); ps.setInt(1, id_user); ResultSet rs = ps.executeQuery(); while (rs.next()) { int followerId = rs.getInt("id_follower"); // 检查当前用户是否关注了这个粉丝(即是否互粉) String sql2 = "SELECT id_user FROM followers WHERE id_user = ? AND id_follower = ?"; PreparedStatement ps2 = connection.prepareStatement(sql2); ps2.setInt(1, followerId); ps2.setInt(2, id_user); ResultSet rs2 = ps2.executeQuery(); // 查询有结果则说明是互粉用户 if (rs2.next()) { data.add(new Object[]{getFollowerName(followerId)}); } ps2.close(); rs2.close(); } ps.close(); rs.close(); // 不要关闭connection!否则后续数据库操作会报错 return data; } catch (SQLException e) { JOptionPane.showMessageDialog(null, "listMutualFollowers():" + e.getMessage()); return null; } }
关键修正点:
- 第二个查询添加
id_follower = ?条件,验证当前用户是否在该粉丝的关注列表中 - 用占位符替代SQL拼接,避免注入风险
- 仅在确认是互粉时才添加用户名称,而非把粉丝的所有关注者都加入
- 移除
connection.close(),数据库连接通常由连接池管理,不应在方法内随意关闭
额外注意事项
- 原代码
ArrayList未指定泛型,建议改为ArrayList<Object[]>,避免类型转换问题 - 单独调用
e.getMessage()无意义,直接在弹窗中使用即可 - 数据库连接不要在方法内关闭,否则会导致连接泄漏或后续操作失败
内容的提问来源于stack exchange,提问作者João Victor
相关产品推荐
相关产品推荐

