我有这个过程,在一个表中我们有一系列项目动作 应用于其他表格的项目&股票。基本上,项目移动表由以下实体映射:
public class ItemMovement {
enum ItemMovementStatus { NEW, APPLIED }
private Long movementId;
private String itemName;
private String itemCategory;
private String arbitraryQualifier;
private Date movementDate;
private ItemMovementStatus status;
// getters & setters
}
库存商品实体如下:
public class InventoryItem {
private String itemName;
private Double itemStock;
private String arbitraryQualifier;
// getters & setters
}
在一个月内生成移动,在此过程中所有移动必须“应用”到库存表。 “应用”移动意味着从库存表的STOCK值中存在精确匹配,从而基本上减去每个给定移动的ITEM_MOVEMENT_QTY。如果存在至少具有所需移动量的精确匹配,则完成作业。如果没有,我们只是采取我们可以做的,并继续从另一个属于同一ITEM_CATEGORY的项目中获取。如果最后一个库存物品没有足以完成所请求的移动数量,我们必须从共享与移动物品相同的ARBITRARY_QUALIFIER的库存物品中获取。 最后一个问题是,这个ARBITRARY_QUALIFIER的匹配可以来自每个运动项目的数百甚至数千个“匹配”,因为,正如其名称所暗示的,这个限定符可以涉及两个“完全”不相关的项目。在最坏的情况下(非常糟糕),尽管非常远,但所有库存物品应该可以匹配给定的物品移动。
最初我想要检索所有匹配(以块为单位,即查询是“分页”),如下所示:
select m,i from ItemMovement m, InventoryItem i where
m.itemname=i.itemname
or m.itemCategory=i.itemCategory
or m.arbitraryQualifier=i.arbitraryQualifier
然后以非常面向OO的方式处理所有匹配的每个动作,但是当拥有超过20K的动作和20K的库存项目时,这需要花费太多时间。我实际上可以看到检索数据的查询(即使在分页时)花费了太多时间(每页超过一分钟)。花费太多时间本身不是问题,而是禁止我持续超过10分钟的约束。我知道我可以增加这个值,但我想知道我采取的方法是否正确。 我当然希望保持一种非常好的方法,以便完全控制物品移动的过渡并保持算术非常清晰。我相信这里的“真实”问题是:
¿OO是做这种“善意”过程的正确“方式”吗?如果是这样,是否有一种设计模式可以更好地解决我在代码性能,可维护性方面的问题? ¿这是一个我应该查看的过程,例如,PL / SQL存储过程吗?
我正在使用EJB,JPA(Hibernate)。数据库是Oracle。
谢谢,
答案 0 :(得分:1)
hibernate不是为批处理操作而设计的。 使用PL / SQL过程可以获得比使用hibernate更好的性能。
在决定是使用java还是使用PL / SQL时,必须考虑整个系统架构。在大多数情况下,可以通过休眠获得足够的批处理作业性能。
无论您选择什么,通常都有提高给定体系结构性能的方法。
hibernate需要考虑的一个非常重要的事情是如何访问对象。您希望使用少量SELECT
操作从数据库加载对象。如果使用2 SELECT
(每种对象类型一个)加载所有对象,则使用20000(每次移动一个)时,您的工作很可能会更快。