首页 > 解决方案 > 使用 ResultSetMapper 解析结果时无法获取所有行

问题描述

我使用 Java 8 和Jdbi 2.78 版来查询数据库。

我有一个商家的键值配置表。

在此处输入图像描述

我有一个查询数据库的类:

import com.clevergift.gson.MerchantConfigsBeanMapper;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
import java.util.Map;

public abstract class MerchantConfigDAO {

    @Mapper(MerchantConfigsBeanMapper.class)
    @SqlQuery("SELECT configKey, configValue FROM merchant_configs where merchant = :merchant")
    public abstract Map<String, String> getMerchantConfigs(@Bind("merchant") String merchant);

}

并且MerchantConfigsBeanMapper该类应该循环遍历结果:

import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.ResultSetMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class MerchantConfigsBeanMapper implements ResultSetMapper<Map<String, String>> {

    @Override
    public Map<String, String> map(int index, ResultSet r, StatementContext ctx) throws SQLException {

        Map<String, String> configs = new HashMap<String, String>();

        int rowcount = 0;
        if (r.last()) {
            rowcount = r.getRow();
            r.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element
        }
        while (r.next()) {
            configs.put(r.getString("configKey"), r.getString("configValue"));
        }

        return configs;
    }
}

当我在“adidas”中运行这个传递时,显然应该返回 3 个结果。但是,r始终只包含 1 个结果并且r.getString("configValue")cbadmin. r.last()始终为真,因为只返回 1 个结果。

这怎么可能?为什么不r包含所有结果?

编辑

我从服务中调用了 MerchantConfigDAO:

import com.clevergift.services.MerchantConfigService;
import com.google.inject.Inject;
import java.util.Map;

public class MerchantConfigServiceImpl implements MerchantConfigService {
    private MerchantConfigDAO merchantConfigDAO;

    @Inject
    public MerchantConfigServiceImpl(MerchantConfigDAO merchantConfigDAO) {
        this.merchantConfigDAO = merchantConfigDAO;
    }

    public Map<String, String> getMerchantConfigs(String merchant) {
        Map<String, String> merchantConfigs = this.merchantConfigDAO.getMerchantConfigs(merchant);
        return merchantConfigs;
    }
}

即使在此处实施@ivans answer 后,merchantConfigs长度仍为 1...

标签: javajdbi

解决方案


映射器应使用以下代码一次映射一行。从文档:

为结果集中的每一行调用一次行映射器。

@Override
public Map<String, String> map(int index, ResultSet r, StatementContext ctx) throws SQLException {
    Map<String, String> configs = new HashMap<String, String>();
    configs.put(r.getString("configKey"), r.getString("configValue"));
    return configs;
}

如果您仍想ResultSet在一个呼叫中处理整个过程,则需要 return List<Map<String, String>>。中map的每一行一个ResultSet

根据文档

查询方法可能返回单行或多行结果,具体取决于方法返回类型是否看起来像一个集合

更改您的 DAO 方法以返回List<Map<String, String>>


推荐阅读