Spring JDBCを使用していますが、何が最善か疑問に思います。すべてのテーブルを結合して、入力するオブジェクトのすべての関連付けを取得したり、複数の選択クエリを実行したりできますか?オブジェクトのすべてのデータを取得するために複数のテーブルを結合する必要がある場合、Springでテーブルの結合をどのように処理しますか?
1 に答える
一般的に、オブジェクトから参照する数のテーブルを結合することをお勧めします。戻す列の数が多すぎて、残りのデータに対してデータベースを複数回呼び出すという欠点を上回る可能性はほとんどありません。
これに対する唯一の実際の例外は、多対1の関連付けからのデータが必要な場合です。したがって、たとえば、を選択Car
してsに参加すると、Wheel
車ごとに4行が返されますが、これは実際には問題ではありません。ただし、とに参加するWheels
とSeats
、4席の車で16列に戻ります。この種の参加はデカルト積を作成するため、この場合、数台の車しか選択しない場合を除いて、座席を取得するための2番目のクエリが必要になる可能性があります。
Spring JDBCを使用して参加するときにマッピングコードを書き換える問題に対処するには、RowMappersを分割することを検討してください。免責事項:私は主にHibernateを使用しており、SpringのJdbcTemplateについては使用したことがありますが、あまり詳しくありません。1対1の結合の例を挙げましょう。
private Car mapCar(ResultSet rs) throws SQLException {
Car car = null;
while (rs.next()) {
if (car == null) {
Long carId = rs.getLong("ID");
String model = rs.getString("MODEL");
car= new Car(carId, model);
}
car.setEngine(mapEngine(rs));
}
return car;
}
車に固有のmapEngine()
メソッドを含めることも、から呼び出すクラスでパブリックメソッドを作成することもできます。後者を使用する場合は、名前が競合する可能性があるため、選択変数のエイリアシングが適切である可能性があります。それでも、両方に含まれている場合は、別のパブリックマッパーを作成する以外に選択肢がない場合があります。したがって、次のようなパブリックメソッドがある可能性があります。CarRepository
mapEngine()
EngineRepository
mapCar()
CarMapper
EngineMapper
rs.getLong("ID")
public Engine mapEngineShared(ResultSet rs) throws SQLException {
Engine engine = new Engine();
engine.setId("ENGINE_ID"); // Aliased from "ID"
engine.setId("ENGINE_MODEL_TYPE"); // Aliased from "MODEL_TYPE"
return engine;
}
ENGINE_
また、このようにマップするクエリでは、共有マッパーとの互換性のために、エンジンフィールドのエイリアスを必ず作成してください。これは理想的なソリューションではありませんが、どこにでもマッピングコードが重複するのを防ぐことができます。
1対多の関連付けの場合、一度に1つの行のみを処理し、ごとに複製を提供するResultSetExtractor
ため、を使用する必要があります。ただし、アプローチは同じですが、必要に応じて再利用します。RowMappers
Cars
Wheel
RowMappers
データモデルとビジネスロジックが複雑な結合を必要とする傾向があり、マッパーの作成が厄介であるために複雑な結合を頻繁に使用することになった場合は、マッピングを処理するORMソリューションを検討することをお勧めします。繰り返しになりますが、結合を使用しないことによるパフォーマンスの問題が実際に見られない場合は、結合をめったに使用せず、JdbcTemplateの単純さに固執する方がよい場合があります。