Java 如何将RepositoryItem强制转换为ATG上的订单

Java 如何将RepositoryItem强制转换为ATG上的订单,java,atg,Java,Atg,我是ATG的新手,我没能做一些看起来相当简单的事情 我正试图通过订单号在数据库中获取订单。但是这个数字不是orderId,所以我不能只使用OrderManager.loadOrder方法 这是我目前掌握的代码: Repository orderRepository = getOrderManager().getOrderTools().getOrderRepository(); RepositoryView view = orderRepository.getView("order"); Rq

我是ATG的新手,我没能做一些看起来相当简单的事情

我正试图通过订单号在数据库中获取订单。但是这个数字不是orderId,所以我不能只使用OrderManager.loadOrder方法

这是我目前掌握的代码:

Repository orderRepository = getOrderManager().getOrderTools().getOrderRepository();
RepositoryView view = orderRepository.getView("order");

RqlStatement statement = RqlStatement.parseRqlStatement("orderNumber EQUALS ?0");
Object params[] = { pOrderNumber };
RepositoryItem items[] = statement.executeQuery(view, params);

RepositoryItem order = null;
if( (items != null) && (items.length > 0) ) {
    order = items[0];
}

//Now I want to convert this order of type "RepositoryItem" to an actual Order object
我可以通过获取存储库ID并从OrderManager调用loadOrder来实现这一点,但这看起来像是回到数据库并再次找到我手中已经有的东西


是否有其他方法可以从这个RepositoryItem对象中获取实际的Order对象?

这实际上取决于您要做什么

关于项目是从数据库还是从缓存加载的问题取决于存储库设置以及延迟加载设置。有关这方面的文档可以找到

如果要更新订单,则应使用
OrderManager.loadOrder()
,因为这将确保订单得到正确更新,并允许您重新定价订单并更新构成订单的其他存储库项目,如付款组和装运组(记住使用事务包装器以确保订单安全更新)

如果您只是尝试读取值,那么使用存储库方式会更快。我建议您创建一个表单处理程序引用的全局范围的组件。大致如下(下面的代码未测试):

OrderTools.properties文件:

$class=com.acme.commerce.order.OrderTools
$scope=global
orderRepository=/atg/commerce/order/OrderRepository
OrderTools类:

public class OrderTools extends GenericService


{

private RepositoryView orderView;

private RqlStatement orderStm;

private OrderRepository orderRepository;

private OrderManager orderManager;

public void doStartService() throws ServiceException
{
    try
    {
        orderView = getOrderRepository().getView(CommerceConstants.ORDER);
        orderStm = RqlStatement.parseRqlStatement("uniqueOrderId = ?0");

    } catch (RepositoryException e)
    {
        throw new ServiceException(e);
    }
}

protected RepositoryItem getOrderItem(final String uniqueOrderId) throws RepositoryException
{
    Object params[] = new Object[1];
    params[0] = uniqueOrderId;

    RepositoryItem[] orderItems = orderStm.executeQuery(orderView, params);
    if (orderItems != null)
    {
        return getOrderRepository().getItem(orderItems[0].getRepositoryId(), CommerceConstants.ORDER);
    } else
    {
        return null;
    }
}

/*
 This method demonstrates how to load an order using the OrderManager.loadOrder() method.

 The code includes some basic timing so that a performance comparison can be done with the loadOrderSubItemsRepositoryMethod()
 */

public void loadOrderUsingOrderManager(String orderId) {

    long startTime = System.currentTimeMillis();

    Order order = getOrderManager().loadOrder(orderId);

    long orderLoadTime = System.currentTimeMillis();

    //read your properties here ...

    long totalTime = System.currentTimeMillis();

    if(isLoggingDebug()) {
        logDebug("The order load time was " + (orderLoadTime - startTime) + "ms");
        logDebug("The time to read the list of properties was " + (totalTime - startTime) + "ms");
    }

}

/*

This method shows how to get order items such as payment groups or shipping groups using the repository.

*/

public void loadOrderSubItemsRepositoryMethod(MutableRepositoryItem orderItem) {

    long startTime = System.currentTimeMillis();


    // Example of how to get the payment groups using the repository
   MutableRepositoryItem paymentGroups = (List) orderItem.getPropertyValue("paymentGroups");

    // Put code here to iterate through the list of items you want to read

    // Examploe of how to get the shipping groups
    MutableRepositoryItem shippingGroups = (List) orderItem.getPropertyValue("shippingGroups");

    long totalTime = System.currentTimeMillis();

    if(isLoggingDebug()) {
        logDebug("The order load time was " + (orderLoadTime - startTime) + "ms");
        logDebug("The time to read the list of properties was " + (totalTime - startTime) + "ms");
    }


}


public MutableRepository getOrderRepository()
{
    return orderRepository;
}

public void setOrderRepository(final MutableRepository orderRepository)
{
    this.orderRepository = orderRepository;
}

public OrderManager getOrderManager()
{
    return orderRepository;
}

public void setOrderRepository(final OrderManager orderManager)
{
    this.orderManager = orderManager;
}

}

希望这能有所帮助。

如果您只需要订单项目本身的属性,那么您可以使用
getPropertyValue
方法直接从RepositoryItem检索它们。如果您发现要使用
OrderImpl
包装器及其关联的便利方法,那么您应该检索
Order
通过
OrderManager.loadOrder()创建对象实例
方法,正如您所建议的。虽然这将需要应用程序稍微多做一些工作来构建
订单
包装器,但这并不一定意味着对订单表进行另一次DB调用。假设您没有禁用订单项的存储库缓存,那么ATG将利用已缓存的订单存储库项en它正在为您构建
OrderImpl
包装器。当您对order by orderNumber进行RQL查找时,此项将被缓存,因此不会执行冗余的DB调用


请注意,如果尚未缓存相关订单项目(即付款组、装运组、商业项目等),则可能需要额外的DB调用来检索这些项目.

这是一个后端作业,还是在表单处理程序或droplet中?我正在将其添加到OrderManager的子类中,但我需要它在表单处理程序中实际验证表单的输入。如果您试图从自定义属性“orderNumber”查询,则不,没有现成的方法可供使用。使用repository API直线上升是你最好的选择。这正是我正在做的。我简直不敢相信我必须得到同一个对象两次……ATG有那么糟糕吗?“ATG有那么糟糕吗?”-一个好的商人从不责怪他的工具。我已经得到了RepositoryItem对象。我想要Order对象…我不需要更新它,只需要读取一些值。这有关系吗?我需要像订单账单地址上的电子邮件,也许还有一些其他的东西,我通过使用一些由其他开发人员实现的自定义方法获得,这些方法只有接受Order对象作为参数。现在我正在调用loadOrder并获取Order对象……我希望ATG足够聪明,可以将此对象保存在缓存中或其他什么地方,否则我会觉得我要到数据库两次才能获取相同的内容。听起来像loadOrder()如果您只想从与订单相关联的各种存储库项目中读取一些值,这就太过了。@Trindade从您的代码片段中不清楚您在哪里运行代码?因此这可能会有帮助:1)它使用了一个全局范围的组件,可以重复使用;2) 它对
OrderView
和准备好的
RQLStatement
使用
doStartService();3)它向其他人展示了如何使用
.properties
文件配置组件问题是,您仍在使用RespositoryItem,我试图找到一种方法来获取Order对象,而不必使用RepositoryItem id调用loadOrder。如果不可能,我希望至少能确定这一点,并希望ATG能以某种方式缓存这些信息,从而避免另一次数据库访问。我明白了,谢谢,很高兴知道我的解决方案没有那么糟糕。。。我将确认这是答案,因为你清楚地回答了我的主要问题。我会稍等一下,看看是否有更多的人可以在这件事上增加任何东西来考虑关闭。