3

Spring JDBC を使用して、DB からビジネス モデル エンティティにデータをロードします。私の DAO インターフェイスは、JdbcDaoSupport クラスを拡張するクラスによって実装されます。これらのクラスは、RowMapper クラスを使用してエンティティを作成する責任があります。次に、すべての DAO インターフェイスを保持し、ビジネス エンティティを要求するモデル クラス (ビジネス ロジック クラス) へのゲートウェイとして機能するファサード クラスを作成します。遅延読み込みがないため、すべてのビジネス エンティティ データが一度に読み込まれます。ほとんどの場合はこれで問題ありませんが、DB からデータを遅延ロードしたい場合もあります。

たとえば、DB からすべての注文を取得し、日付が特定の条件 (ビジネス ロジック) を満たす場合にのみ注文の詳細を読み込みたいとします。これが私のデザインの簡単な例です。必要に応じて Order Detail データの遅延読み込みをサポートできるように、設計を改善する方法を探しています。ビジネス ロジック クラスでわかるように、ProcessOrder メソッドは、注文日が今日の場合にのみ注文の詳細を必要とし、それ以外の場合は詳細を気にしません。ただし、私の DAO は、ファサード クラスで Order をクエリするときに、すべての Order Details を読み込みます。

1 つの方法は、DAO および Facade クラスで GetOrderDetails メソッドを公開し、必要に応じてビジネス ロジック クラスがそれをロードできるようにすることだと理解しています。しかし、それは私にはうまくいきません。ここでは非常に単純なケースについて説明しましたが、ビジネス オブジェクトが別の変換レイヤーに渡される複雑なシナリオがあり、これらのレイヤーにデータの遅延部分の読み込みを任せたくない場合があります。

また、Hibernate などの ORM ツールを使用することもできます。ただし、私のアプリケーションでは、このケースが適用できる場所はごくわずかであり、ORM ツールを使用してこの動作を実現するのはやり過ぎだと感じています。

私は特別なケースでこれを実現するためのシンプルなデザインだけを探しています。ヘルプ/提案をありがとう。

class Order // Simple POJO business entity
{
   int OrderID;
   Date OrderDate;
   Collection<OrderDetail> OrderDetails; // Need to load lazily
}

class OrderDetail //Simple POJO business entity
{
   Order order;
   int ItemID;
   double Cost;
   int Quantity;
}

// DAO Interface
interface OrderDAO
{
   Order getOrder(int aOrderID);
}

// Concrete DAO class
JdbcOrderDao extends JdbcDaoSupport implements OrderDao
{
   Order getOrder(int aOrderID)
   {
      Order order = getJdbcTemplate.query(....., new OrderRowMapper());
      populateOrderDetails(order);
      return order;
   }

   private PopulateOrderDetails(Order aOrder)
   {
      //Query the DB and fill the Order details data.
   }

   private class OrderRowMapper implements ParameterizedRowMapper<Order>
   {
      // Code implemented to create and return the business entity from the resultset;
   }
}

// Facade class that hides the DAO interface and exposes the business methods
ServiceFacade
{
   private OrderDAO orderDAO;

   public Order GetOrder(int aOrderID)
   {
      return orderDAO.getOrder(aOrderID);
   }
}

// Business Logic class
BusinessModelLoader
{
   List<Order> Orders = new ArrayList<Order>();
   LoadOrders()
   {
     for(Integer orderID : allOrderIDs)
       Orders.add(facade.getOrder(orderID));
   }

   ProcessOrders()
   {
      for(Order order: Orders)
      {
         if (order.OrderDate == Today)
         {
            List<OrderDetail> details = order.OrderDetails; // Need to perform lazy loading here automatically
            // Do something with details
         }
      }
   }
}
4

3 に答える 3

-1

私があなたの質問を理解できる範囲で、これが私の返事です。

Order オブジェクトに Order Details を遅延ロードしたいとします。そのためにLAZY=trueは、マッピング ファイルのように、またはfetch=FetchType.LAZY注釈を使用している場合は、Order Details コレクションを設定する必要があります。

Order オブジェクトを照会すると、注文の詳細は必要になるまでロードされません。

これで、DAO クラスで getOrder を実行した後にセッションが閉じられるため、遅延ロードされたオブジェクトをビジネス レイヤーで使用できなくなります。そのためには、オブジェクトを返す前に DAO メソッドで次のことを行います

Hibernate.initialize(order.getOrderDetails());

私はあなたの質問に答えたことを願っています。

于 2012-11-05T18:36:30.177 に答える