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

数据库查询获2行数据,返回Map仅保留最后一行的问题咨询

问题排查:Map仅保留最后一行数据的原因及解决办法

核心问题原因

你遇到的问题本质是Map的键唯一性约束:

  • 你的SQL查询返回了2行记录,但这两行的id字段值是完全相同的(毕竟WHERE条件是id="+id,能返回2行说明这两行的id一致但name不同,distinct是整行去重,所以会保留这两条记录)。
  • 当你用重复的id作为Map的键时,第二次调用put()方法会直接覆盖第一次存入的对应值——Map的规则就是键唯一,新值覆盖旧值,所以最终只会留下最后一次存入的键值对。

快速验证方式

你可以在循环里加一行打印,确认两次循环的键是否重复:

while (itr.hasNext()) {
    Object row1[] = (Object[]) itr.next();
    Integer key = row1[0]==null?0:Integer.parseInt(row1[0].toString());
    String value = (row1[1] == null)? "" : row1[1].toString();
    System.out.println("当前键:" + key + ",对应值:" + value); // 打印验证
    stylesMap.put(key, value);
}

运行后你会发现两次循环的key是同一个值,这就是覆盖问题的直接证据。

针对性解决方案

根据你的业务需求,有两种常见的处理方式:

1. 保留同一ID下的所有Name:用List作为Map的值

如果业务上允许同一个ID对应多个Name,可以把Map的类型改成Map<Integer, List<String>>,这样同一个ID下的所有Name都能被保存:

public Map<Integer, List<String>> getname(int id) {
    Session session = sessionFactory.openSession();
    Map<Integer, List<String>> stylesMap = new LinkedHashMap<>();
    try {
        Query query = getSession().createSQLQuery("select distinct id,name from employee where id=:id");
        query.setParameter("id", id); // 改用参数化查询避免SQL注入
        List results = query.list();
        Iterator itr = results.iterator();
        while (itr.hasNext()) {
            Object row1[] = (Object[]) itr.next();
            Integer key = row1[0]==null?0:Integer.parseInt(row1[0].toString());
            String value = (row1[1] == null)? "" : row1[1].toString();
            
            // 如果键不存在,先创建空List;存在则直接添加值
            stylesMap.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
        }
    } catch (Exception e) {
        logger.error("", e);
    } finally {
        if(session !=null) {
            session.close();
        }
    }
    return stylesMap;
}

2. 直接返回所有行数据:改用List存储

如果不需要用Map结构,直接返回包含所有行的List会更直观,比如用List<Map<String, Object>>存储每一行的id和name:

public List<Map<String, Object>> getname(int id) {
    Session session = sessionFactory.openSession();
    List<Map<String, Object>> resultList = new ArrayList<>();
    try {
        Query query = getSession().createSQLQuery("select distinct id,name from employee where id=:id");
        query.setParameter("id", id);
        List results = query.list();
        Iterator itr = results.iterator();
        while (itr.hasNext()) {
            Object row1[] = (Object[]) itr.next();
            Map<String, Object> rowMap = new HashMap<>();
            rowMap.put("id", row1[0]==null?0:Integer.parseInt(row1[0].toString()));
            rowMap.put("name", (row1[1] == null)? "" : row1[1].toString());
            resultList.add(rowMap);
        }
    } catch (Exception e) {
        logger.error("", e);
    } finally {
        if(session !=null) {
            session.close();
        }
    }
    return resultList;
}

额外提醒

你的原SQL存在SQL注入风险,上面的解决方案里已经改成了参数化查询,这是生产环境必须注意的安全细节。

内容的提问来源于stack exchange,提问作者Chakravarthirudhir Reddy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:37:28