春季JDBC中的多个一对多关系

2022-09-03 15:37:22

我正在使用Spring JDBC,我有点不确定如何处理多个一对多关系(或多对多关系)。在本例中,我将一个存储库注入到我的一个结果文本元器件中,以便可以检索其关联。这是这样做的方法吗?不好吗?还有其他更好的方法吗?

注意:我省略了存储库的注入

public class SomeResultSetExtractor implements ResultSetExtractor {

  public Object extractData(ResultSet rs) throws SQLException, DataAccessException {
    List result = new LinkedList();

    while (rs.next()) {
        SomeObject object = new SomeObject(rs.getString(1), rs.getLong(2));
        result.add(object);

        List<AnotherObject> otherObjects = anotherRepository.findAllById(object.getId);
        object.setOtherObjects(otherObjects);
        // and so on
    }

    return result;

  }
}

Okey,所以在阅读Dmytro Polivenok答案后,我已经改为RowMapper接口,我目前正在使用其他存储库来填充所有关联,就像我在示例中所示的那样。这是一个好方法吗?


答案 1

我认为Spring JDBC和SQL查询的一个很好的做法是为每个实体使用一个查询。

例如,假设此模型:

  • 客户(客户 Id、姓名、年龄等)
  • 地址(客户 Id、类型、街道、城市等)
  • 付款选项(客户 ID、卡号、卡类型等)

  • 客户 1---* 地址

  • 客户 1---* 付款选项

我会构建3个查询,3个Daos,3个ResultSetExtractors/RowcallbackHandlers:

  • CustomerDao with readCustomerData(Customer or List)
  • 地址Dao与读取地址为客户(客户或列表)
  • 支付选项多与读取支付选项为客户(客户或列表)

如果要在 1 个查询中烘焙它,则必须构建一些逻辑来还原 cartasian 产品。

  • 即,如果客户有 3 个地址和 2 个付款选项,则查询将返回 6 行。
  • 如果地址或付款选项没有自己的主键,这将变得非常困难。

对于许多人到许多人来说:

  • 客户 * --推荐 -- * 产品

我可能会构建:

  • 客户道.阅读推荐和产品密钥
  • getDistinctListOfProductKeysFrom推荐
  • 产品展示Dao.read产品展示
  • 替换产品密钥按产品下推荐

像这样,你可以重用 ProductDao.readProducts

  • 客户 * --购买 -- * 产品或
  • 产品组 1---* 产品

答案 2

我认为你的代码会起作用,但这里关注的是ResultSetExtractor的使用,它主要用于JDBC框架本身,并且在大多数情况下,文档建议使用RowMapper。

因此,另一种方法是在DAO中使用选择和映射父对象的方法。然后,每个对象调用选择和映射子对象的其他 Repository 或私有方法,然后根据您的关系类型(单向或双向)将子对象与父对象链接起来。此方法还允许您控制是否要加载子对象。

例如,您可以检查具有SimpleJdbc临床类的Spring PetClinic应用程序

如果你可以使用其他框架,你可以考虑mybatis,它更多的是关于映射,并允许你控制你的SQL代码。


推荐