You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:20:37