原因是queryForList()与queryForObject()这两个方法一般情况下只返回单一列的数据,不能反悔复杂的数据对象。比如有实体类user,就会报错。
public class User(){
private String name;
privtae Stirng sex;
}
看源码可以发现反悔的确实只会是单一列的数据:
@Nullable
public <T> T queryForObject(String sql, SqlParameterSource paramSource, Class<T> requiredType) throws DataAccessException {
return this.queryForObject(sql, (SqlParameterSource)paramSource, (RowMapper)(new SingleColumnRowMapper(requiredType)));
}
public <T> List<T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType) throws DataAccessException {
return this.query(sql, (SqlParameterSource)paramSource, (RowMapper)(new SingleColumnRowMapper(elementType)));
}
public <T> List<T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType) throws DataAccessException {
return this.queryForList(sql, (SqlParameterSource)(new MapSqlParameterSource(paramMap)), elementType);
}
如果想要返回自定义的复杂对象怎么办呢?使用query方法或者public List<Map<String, Object>> queryForList方法
但是我们可以看到其实public List<Map<String, Object>> queryForList方法也是调用的query方法。
public List<Map<String, Object>> queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException {
return this.query(sql, (SqlParameterSource)paramSource, (RowMapper)(new ColumnMapRowMapper()));
}
public List<Map<String, Object>> queryForList(String sql, Map<String, ?> paramMap) throws DataAccessException {
return this.queryForList(sql, (SqlParameterSource)(new MapSqlParameterSource(paramMap)));
}
想要调用query方法返回List<User>还需要实现RowMapper接口,代码如下:
@Getter
@Setter
public class User implements RowMapper{
private String name;
private String sex;
@Nullable
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
// 这里的序号是列的序号,以1开始
user.setName(resultSet.getString(1));
user.setSex(resultSet.getString(2));
return user;
}
}
这样就可以获取到想要的List了
JdbcTemplate.query("select * from user", new User());
使用MyBatis习惯之后,惯性思维看到queryForList就以为会是自己想要的功能,查了很久才发现原来是这个错误,以后遇到问题还是要仔细看源码。
微信公众号:二虎程序