如何使用JDBCTemplate正确获取Map类型列表数据
问题根因
JdbcTemplate.queryForMap()仅用于返回单行查询结果,返回值是单条Map<String, Object>(key为列名、value为对应列值),本身不支持返回多行列表,用它查询全表多数据自然拿不到预期结果。- 直接调用单参数的
queryForList(String sql)方法时,虽然方法签名标注返回List<Map<String, Object>>,但受Java泛型类型擦除影响,部分Spring版本、特定JDBC驱动场景下会出现类型不匹配警告,甚至运行时抛出类型转换异常,无法直接拿到类型安全的结果。
正确操作方案
方案1:调用重载的queryForList方法(最简实现)
使用带参数位声明的queryForList重载方法,显式告知框架传入参数情况,由Spring自动完成行到Map的映射:
// 替换为实际业务SQL String querySql = "SELECT * FROM table_name;"; // 第二个参数为SQL占位符对应的参数数组,无参数时传空数组即可 List<Map<String, Object>> mapList = jdbcTemplate.queryForList(querySql, new Object[]{});
该方式返回的结果中,每个Map对应一行表数据,key为查询返回的列名,value为JDBC驱动自动映射后的Java类型值:比如INT字段映射为
Integer、BIGINT映射为Long、VARCHAR映射为String、DATETIME映射为java.sql.Timestamp,常规场景下直接使用即可。
方案2:显式传入行映射器(适合需要自定义转换的场景)
如果需要自定义列值转换规则、统一列名大小写适配,可以调用query方法,传入ColumnMapRowMapper实例做映射,可控性更高:
import org.springframework.jdbc.core.ColumnMapRowMapper; import java.sql.ResultSet; import java.sql.SQLException; // 业务SQL String querySql = "SELECT * FROM table_name;"; List<Map<String, Object>> mapList = jdbcTemplate.query(querySql, new ColumnMapRowMapper() { @Override protected Object getColumnValue(ResultSet rs, int index) throws SQLException { // 可在此处添加自定义转换逻辑,比如将BLOB字段转为byte数组、将时间戳转为LocalDateTime等 return super.getColumnValue(rs, index); } @Override protected String getColumnKey(String columnName) { // 可在此处统一列名格式,比如全部转小写,避免不同驱动返回列名大小写不一致导致的key匹配问题 return columnName.toLowerCase(); } });
无自定义转换需求时,直接传入
new ColumnMapRowMapper()即可,返回结果和方案1完全一致,使用前需要导入org.springframework.jdbc.core.ColumnMapRowMapper包。
常见类型匹配问题排查
- 若取Map值时出现类型转换异常:先确认对应数据库字段的JDBC默认映射类型,不要做跨类型强转,比如Long类型值不要直接强转成Integer。
- 若按列名取不到值:检查JDBC驱动返回的列名大小写,可通过方案2中重写
getColumnKey方法统一列名格式,避免大小写不匹配问题。 - 若返回列表为空:先在数据库客户端执行相同SQL确认有返回数据,同时检查JdbcTemplate绑定的数据源是否连接到正确的数据库实例。
内容的提问来源于stack exchange,提问作者Riya Doshi
相关产品推荐
相关产品推荐

