15

私は Spring JDBC を使用していますが、複数の 1 対多の関係 (または多対多) を操作する方法が少しわかりません。この場合、resultsetextractor の 1 つにリポジトリを挿入して、その関連付けを取得できるようにします。これはそれを行う方法ですか?悪いですか?他に良い方法はありますか?

注:リポジトリの注入を省略しました

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;

  }
}

Dmytro Polivenok の回答を読んだ後、代わりに RowMapper インターフェイスに変更しました。現在、例に示すように、他のリポジトリを使用してすべての関連付けを設定しています。これは良い方法ですか?

4

2 に答える 2

5

一般的に、Spring JDBC および SQL クエリの良い方法は、エンティティごとに 1 つのクエリを使用することだと思います。

たとえば、次のモデルを想定します。

  • 顧客 (customerId、名前、年齢、...)
  • 住所 (customerId、タイプ、番地、都市など)
  • PaymentOption (顧客 ID、カード番号、カードタイプ、...)

  • 顧客 1---* 住所

  • 顧客 1---* 支払いオプション

3 つのクエリ、3 つの Daos、3 つの ResultSetExtractors/RowcallbackHandlers を構築します。

  • readCustomerData(Customer または List) を使用した CustomerDao
  • readAddressForCustomer(顧客またはリスト) を使用した AddressDao
  • readPaymentOptionsForCustomer(Customer または List) を使用する PaymentOptionDao

これを 1 つのクエリにまとめると、デカルト積を元に戻すロジックを構築する必要があります。

  • つまり、顧客が 3 つの住所と 2 つの支払いオプションを持っている場合、クエリは 6 行を返します。
  • Address または PaymentOption に独自の主キーがない場合、これは非常に難しくなります。

多対多の場合:

  • 顧客 * -- 推奨 -- * 製品

私はおそらく構築します:

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

このように、 ProductDao.readProducts を再利用できます

  • 顧客 * --buys-- * 製品または
  • ProductGroup 1---* 製品
于 2013-03-28T05:58:31.687 に答える
4

あなたのコードは機能すると思いますが、ここでの懸念は、主に JDBC フレームワーク自体のための ResultSetExtractor の使用に関するものであり、ほとんどの場合、ドキュメントでは RowMapper の使用が推奨されています。

したがって、別のアプローチは、DAO に親オブジェクトを選択してマップするメソッドを含めることです。次に、オブジェクトごとに、子オブジェクトを選択してマップする他のリポジトリまたはプライベート メソッドを呼び出し、関係タイプ (一方向または双方向) に基づいて子オブジェクトを親にリンクします。このアプローチにより、子オブジェクトをロードするかどうかを制御することもできます。

たとえば、SimpleJdbcClinic クラスを持つ Spring PetClinic アプリケーションを確認できます。

他のフレームワークを使用できる場合は、mybatisを検討してください。これはマッピングに関するものであり、SQL コードを制御できます。

于 2013-03-19T21:16:11.783 に答える