Spring JDBC中的多个一对多关系

时间:2013-03-19 07:58:23

标签: java spring jdbc spring-jdbc

我正在使用Spring JDBC,我对如何处理多个一对多关系(或多对多关系)有点不确定。在这种情况下,我将一个存储库注入我的resultsetextractors之一,以便我可以检索其关联。这是这样做的吗?这不好吗?还有其他更好的方法吗?

注意:我遗漏了注册库

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界面而我正在使用其他存储库来填充我在我的示例中显示的所有关联。这是一个很好的方式吗?

2 个答案:

答案 0 :(得分:5)

我认为Spring JDBC和SQL查询的一个好习惯是对每个实体使用一个查询。

E.g。假设这个模型:

  • 客户(customerId,姓名,年龄......)
  • 地址(customerId,type,street,city,...)
  • PaymentOption(customerId,cardnumber,cardtype,...)

  • 客户1 --- *地址

  • 客户1 --- * PaymentOption

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

  • 带有readCustomerData(客户或列表)的CustomerDao
  • AddressDao with readAddressForCustomer(Customer or List)
  • PaymentOptionDao with readPaymentOptionsForCustomer(Customer or List)

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

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

对于很多人:

  • 客户* --recommends-- *产品

我可能会建立:

  • CustomerDao.readRecommendationsAndProductKeys
  • getDistinctListOfProductKeysFromRecommendations
  • ProductDao.readProducts
  • replaceProductKeysByProductsOnRecommendations

像这样你可以重用ProductDao.readProducts

  • 客户* - 购买 - *产品或
  • ProductGroup 1 --- * Product

答案 1 :(得分:4)

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

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

例如,您可以查看具有SimpleJdbcClinic class

的Spring PetClinic应用程序

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