我有连接 3 个表的 SQL 查询,其中一个只是连接另外两个表的多对多。我使用 Spring JDBC ResultSetExtractor 将 ResultSet 转换为我的对象,大致如下所示:
class Customer {
private String id;
private Set<AccountType> accountTypes;
...
}
ResultSetExtractor 实现如下所示:
public List<Client> extractData(ResultSet rs) throws SQLException,
DataAccessException {
Map<Integer, Client> clientsMap = new LinkedHashMap<Integer, Client>();
while (rs.next()) {
int id = rs.getInt("id");
// add the client to the map only the first time
if (!clientsMap.containsKey(id)) {
Client client = new Client();
client.setId(id);
...
clientsMap.put(id, client);
}
// always add the account type to the existing client
Client client = clientsMap.get(id);
client.addAccountType(extractAccountTypeFrom(rs, id));
}
return new ArrayList<Client>(clientsMap.values());
}
这在没有分页的情况下工作正常。
但是,我需要对这些结果进行分页。我通常这样做的方式是将其添加到查询中,例如:
SELECT ... ORDER BY name ASC LIMIT 10 OFFSET 30;
但是,由于此查询具有联接,当我限制结果的数量时,我实际上是在限制 JOINED 结果的数量(即,作为客户端出现的次数与其拥有的帐户类型的数量一样多,则应用 LIMIT 不客户的数量,而是客户* accountTypes的数量,这不是我想要的)。
我想出的唯一解决方案是从查询中删除 LIMIT (和 OFFSET 因为这也是错误的)并以编程方式应用它们:
List<Client> allClients = jdbcTemplate.query....
List<Client> result = allClients.subList(offset, offset+limit);
但这显然不是一个非常好的、有效的解决方案。有没有更好的办法?