使用ResultSetMapper解析结果时无法获取所有行
Cannot get all rows when using ResultSetMapper to parse results
我正在使用 Java 8 和 Jdbi 版本 2.78 来查询数据库。
我有 table 个 key-value 个商家配置。
我有一个查询数据库的class:
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
class 应该遍历结果:
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 回答 之后,merchantConfigs
的长度仍然是 1...
映射器应使用以下代码一次映射一行。来自文档:
Row mappers are invoked once for each row in the result set.
@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>>
。 ResultSet
.
中每行一个 map
根据文档
Query methods may return a single- or multi-row result, depending on whether the method return type looks like a collection.
将您的 DAO 方法更改为 return List<Map<String, String>>
我正在使用 Java 8 和 Jdbi 版本 2.78 来查询数据库。
我有 table 个 key-value 个商家配置。
我有一个查询数据库的class:
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
class 应该遍历结果:
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 回答 merchantConfigs
的长度仍然是 1...
映射器应使用以下代码一次映射一行。来自文档:
Row mappers are invoked once for each row in the result set.
@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>>
。 ResultSet
.
map
根据文档
Query methods may return a single- or multi-row result, depending on whether the method return type looks like a collection.
将您的 DAO 方法更改为 return List<Map<String, String>>