我有一个Student实体类
@Data
public class Student {
private String classroom;
private Map<String, String> info;
}
数据库中内容
id classroom name address
1 一班 张三 江苏无锡
2 一班 李四 江苏南通
3 二班 王五 北京
4 二班 赵六 上海
我现在要把SQL查出来的结果的name作为key, address作为value封装到Map里
类似这样的list = [Student(classroom=一班, info={李四=江苏南通, 张三=江苏无锡}), Student(classroom=二班, info={王五=北京, 赵六=上海})]
除了在service层自己写循环外, 单靠SQL的节点能实现吗? 怎么实现? 不过不行的话通过typeHandler可以吗? 怎么写?
String sql = "SELECT name, address FROM student";
Map<String, String> map = jdbcTemplate.query(sql, new ResultSetExtractor<Map<String, String>>() {
@Override
public Map<String, String> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
Map<String, String> map = new HashMap<>();
while (resultSet.next()) {
String name = resultSet.getString("name");
String address = resultSet.getString("address");
map.put(name, address);
}
return map;
}
});
System.out.println(map);
这种情况可以通过自定义结果集处理器(ResultSetHandler)来实现。
你可以写一个类似这样的结果集处理器:
java
public class StudentResultSetHandler implements ResultSetHandler<List<Student>> {
@Override
public List<Student> handle(ResultSet rs) throws SQLException {
Map<String, String> info = new HashMap<>();
while (rs.next()) {
info.put(rs.getString("name"), rs.getString("address"));
}
return Collections.singletonList(new Student(/*classroom*/, info));
}
}
然后在查询时使用这个结果集处理器:
java
List<Student> students = jdbcTemplate.query(
"select * from student",
new StudentResultSetHandler()
);
这个结果集处理器会在遍历结果集的过程中构建info map,并最终返回一个只包含一个Student对象的List。
所以你的查询结果 would be:
students = [Student(classroom=一班, info={张三=江苏无锡, 李四=江苏南通})]
使用自定义结果集处理器是在JDBC层面上实现这个功能的一种方式。你也可以在Service层循环遍历结果集,或者使用MyBatis的ResultMap功能。但使用ResultSetHandler可以更优雅地封装这个逻辑。