Lambda封装JDBC ResultSet的核心是定义RowMapper函数式接口,将字段提取、类型转换、对象赋值逻辑抽象为可传入的Lambda或方法引用,配合泛型查询方法实现资源自动管理与模板代码消除。

用Lambda表达式封装JDBC的ResultSet,核心是把重复的字段提取、类型转换、对象赋值逻辑抽成函数式接口,再通过方法引用或Lambda传入,避免模板代码。
定义通用结果映射函数接口
创建一个函数式接口,接收ResultSet并返回任意类型对象:
@FunctionalInterface
public interface RowMapper<t> {
T mapRow(ResultSet rs) throws SQLException;
}</t>
这个接口就是Lambda要实现的契约。比如封装User对象:
RowMapper<user> userMapper = rs -> new User(
rs.getLong("id"),
rs.getString("name"),
rs.getInt("age")
);</user>
封装可复用的查询执行方法
写一个泛型方法,接受SQL和RowMapper,自动处理资源关闭与异常:
public static <t> List<t> query(String sql, RowMapper<t> rowMapper) throws SQLException {
List<t> list = new ArrayList();
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
list.add(rowMapper.mapRow(rs));
}
}
return list;
}</t></t></t></t>
调用时直接传入Lambda,一行完成映射:
List<user> users = query("SELECT id,name,age FROM user",
rs -> new User(rs.getLong("id"), rs.getString("name"), rs.getInt("age")));
</user>
进一步简化:支持字段名/索引自动匹配
如果实体类字段名和数据库列名一致,可用反射+Lambda减少硬编码:
- 定义工具方法,根据字段名自动调用对应getXXX方法(如name→getString("name"))
- 用Lambda包装该逻辑,例如:
rs -> BeanUtil.mapToBean(rs, User.class) - 结合构造器引用:
User::new需配合ResultSetExtractor适配器,但要注意参数顺序需与构造器严格一致
注意事项与避坑点
Lambda虽简洁,但ResultSet操作仍需注意:
- 不要在Lambda里抛出非SQLException的受检异常,否则需包装为RuntimeException
- ResultSet游标位置由
rs.next()控制,Lambda内无需重复调用 - 空值处理必须显式判断,
rs.getString("xxx")返回null,避免NPE - 不建议在Lambda中执行额外SQL或IO操作,违背单一职责且影响性能










