云夜OVO 2024-03-07 20:28 采纳率: 70%
浏览 6
已结题

基于Springboot实现从数据库获取用户i相似度矩阵时sql语句执行结果不一致

在使用springboot实现基于用户的协同过滤算法中的获取用户相似度矩阵的时候出现了sql语句在数据库中执行的结果和在后端执行的结果不一致的问题。
其中,后端写法如下:

public List<Map<Integer, Double>> getSimilarities(Integer userid1){//获取用户相似度矩阵
        String query = "SELECT  userid2,similarity   FROM similarities where userid1="+userid1;
        List<Map<Integer, Double>> userSimilarity = new ArrayList<>();

        jdbcTemplate.query(query, rs -> {
            while (rs.next()) {
                int userid2 = rs.getInt("userid2");
                double similarity = rs.getDouble("similarity");

                // 将评分数据存入Map
                Map<Integer, Double> userRatingMap = new HashMap<>();
                userRatingMap.put(userid2, similarity);

                // 将Map添加到List中
                userSimilarity.add(userRatingMap);
            }
        });
        return userSimilarity;
    }

这个query语句在数据库里执行结果如下:

img

但是,在后端里打印数据库的返回结果rs的时候却只有一行!

img

数据库里的数据如下:

img

除此之外只有一个userid1,userid2的唯一键约束

img

img

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-07 20:28
    关注

    引自免费微信小程序:皆我百晓生

    在分析这个问题时,首先确认SQL语句执行的环境和上下文是否一致。从你的描述来看,数据库直接执行SQL语句与Spring Boot中通过JdbcTemplate执行该SQL语句的结果不一致。

    针对你提供的代码段,我注意到一个可能的问题:你在处理查询结果时,每次循环都在创建一个新的Map对象并添加到List中,这会导致最终返回的userSimilarity列表中只包含最后一行的用户相似度数据。为了解决这个问题,你应该在一个map中累积所有的userid2和similarity值,然后将这个map添加到list中,而不是每行都创建新的map:

    public List<Map<Integer, Double>> getSimilarities(Integer userid1) {
        String query = "SELECT userid2, similarity FROM similarities WHERE userid1=?";
        List<Map<Integer, Double>> userSimilarity = new ArrayList<>();
    
        jdbcTemplate.query(query, new Object[]{userid1}, rs -> {
            Map<Integer, Double> userRatingMap = new HashMap<>();
            while (rs.next()) {
                int userid2 = rs.getInt("userid2");
                double similarity = rs.getDouble("similarity");
    
                // 将相似度数据存入同一个Map中
                userRatingMap.put(userid2, similarity);
            }
            // 在遍历完所有记录后,将累积了所有相似度数据的Map添加到List中
            userSimilarity.add(userRatingMap);
        });
        return userSimilarity;
    }
    

    同时,请确保SQL注入风险被正确处理,这里使用了?占位符,并在query()方法的第二个参数传入了对应的实际值数组。

    此外,请检查以下几点以确保问题排查无遗漏:

    1. 确保数据库连接配置正确,且在Spring Boot应用运行时连接的是同一数据库实例。
    2. 检查SQL语句中的字符串拼接问题,建议使用PreparedStatement的方式避免SQL注入,如上修改所示。
    3. 确认在调用此方法前,数据库中的数据是稳定的,没有并发写入导致的数据变化。
    4. 如果userid1是一个动态参数,确保传递给方法的参数值与数据库中执行的值相同。

    如果上述修正后的代码仍无法解决您的问题,请提供更多的日志信息或错误提示,以便进一步定位问题所在。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 3月15日
  • 已采纳回答 3月7日
  • 创建了问题 3月7日