Spring JDBC Template:多查询结果映射至单个Customer领域对象
从两张大数据量表关联构建Customer对象的可行方案
假设你的Customer领域对象结构如下(适配一对多的地址关系):
public class Customer { private Long id; private String name; private String phone; private List<String> addresses; // 构造器、Getter/Setter 省略 }
方案1:Map内存关联法(你的尝试完全正确)
这是最直接且高效的实现方式,尤其适合分页处理大数据量场景,步骤如下:
- 先查询客户基础信息,将结果转换为以客户ID为Key的Map,每个Customer对象初始化空地址列表。
- 查询地址表数据,遍历每条记录,通过ID从Map中找到对应Customer并追加地址。
- 最后将Map的Value集合转为List返回。
代码示例:
// 1. 查询客户基础信息并构建Map String customerSql = "SELECT id, name, phone FROM customer_table"; List<Customer> customerList = jdbcTemplate.query(customerSql, (rs, rowNum) -> { Customer customer = new Customer(); customer.setId(rs.getLong("id")); customer.setName(rs.getString("name")); customer.setPhone(rs.getString("phone")); customer.setAddresses(new ArrayList<>()); // 初始化空地址列表 return customer; }); Map<Long, Customer> customerMap = customerList.stream() .collect(Collectors.toMap(Customer::getId, Function.identity())); // 2. 查询地址并关联到对应客户 String addressSql = "SELECT id, address FROM address_table"; jdbcTemplate.query(addressSql, (rs, rowNum) -> { Long customerId = rs.getLong("id"); String address = rs.getString("address"); Customer target = customerMap.get(customerId); if (target != null) { target.getAddresses().add(address); } return null; // 仅做关联操作,无需返回结果 }); // 3. 整理最终结果 List<Customer> finalResult = new ArrayList<>(customerMap.values());
优势:逻辑清晰,无额外依赖;配合分页查询可避免一次性加载全量数据导致内存溢出。
方案2:地址分组后关联
先将地址按客户ID分组,再批量关联到客户列表,写法更简洁:
// 查询客户列表 List<Customer> customers = jdbcTemplate.query( "SELECT id, name, phone FROM customer_table", new BeanPropertyRowMapper<>(Customer.class) ); // 查询地址并按客户ID分组 Map<Long, List<String>> addressGroup = jdbcTemplate.query( "SELECT id, address FROM address_table", (rs, rowNum) -> new AbstractMap.SimpleEntry<>(rs.getLong("id"), rs.getString("address")) ).stream() .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList()) )); // 批量关联地址 customers.forEach(cust -> { cust.setAddresses(addressGroup.getOrDefault(cust.getId(), Collections.emptyList())); });
关键注意事项
- 大数据量必做分页:如果两张表数据量极大,绝对不能一次性查询全量数据,建议按ID分段或使用分页参数,每次处理1000-5000条数据,避免OOM。
- 索引优化:确保两张表的
id字段都建立了索引,提升查询效率。 - 异常处理:地址表中可能存在无效的客户ID(对应客户不存在),必须加判空逻辑避免空指针。
内容的提问来源于stack exchange,提问作者Zee Shan
相关产品推荐
相关产品推荐

