【问题标题】:Filtering of objects in repository or service?过滤存储库或服务中的对象?
【发布时间】:2013-10-04 18:28:24
【问题描述】:

我想根据一些参数获取对象列表。对象是否属于特定类别,是否具有属性 x y z 等。我创建了一个相当简单的存储库,通过 id 获取对象。如果我想要一个基于不同参数和标准的对象列表,您是否会在存储库中添加一个方法来执行此操作,或者在服务层中添加一个方法,直到它有一个符合标准的对象列表?它会简单地使用存储库 get by id 方法并根据许多标准检查它吗?

【问题讨论】:

  • 我不明白。 findById() 如何返回对象列表?无论如何,数据库的全部意义在于能够根据查询返回数据。他们为此而生。所以是的,使用返回你想要的查询。看起来您想阅读所有内容,然后过滤掉一些对象。这不是一个好策略。

标签: java jakarta-ee jpa domain-driven-design


【解决方案1】:

以下策略基于项目也使用域对象作为持久对象。

如果查询仅用于用户搜索(例如,订单搜索 ui),我想直接在接口组件中调用存储库。

@Controller
public class OrderAdminController {
     @RequestMapping(........)
     public String search(@ModelAttribute OrderCriteria criteria) {
          PagedList<Order> orders = orderRepository.findBy(criteria);
          //criteria contains dateWhenPlaced, customerNameLike, orderStatus matching and so on.
          .......
     }
}

如果查询包含领域概念,我想使用规范。在这种情况下,SQL 过滤最终用于基础设施(为了性能,我们不能将所有聚合加载到内存中并通过 java 进行过滤)但域逻辑不会泄漏(到应用层和基础设施)

public class CancelOverdueOrdersBatch {

    public void run() {
        List<Order> overdues = orderRepository.
             findSatisfying(new OverdueOrderSpecification(clock));
        for (Order order: overdues) {
            //.....cancel
        }
    }
}

public class OverdueOrderSpecification {
    private Clock clock;
    private int overdueMinutes = 30;

    public OrderCriteria asCriteria() { //invoked by repository implementation
         return new OrderCriteria.Builder().orderStatusEq(UNPAID).
             placedBefore(overdueMinutesAgo()).build();
    }

    private Date overdueMinutesAgo() {
        return ....//placedDate calculation based on clock.now() and overdueMinutes 
    }
}

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 2011-02-28
    • 2019-09-21
    • 2010-11-22
    • 2011-06-11
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多