我正在使用 Spring JDBC,我想知道什么是最好的:加入所有表以便我可以获得我想要填充的对象的所有关联或执行多个选择查询?当您需要连接多个表以获取对象的所有数据时,如何处理 Spring 中的表连接?
1 回答
一般来说,最好加入从对象中引用的尽可能多的表。您带回的列数不太可能超过为其余数据多次调用数据库的缺点。
唯一真正的例外是如果您想要来自多对一关联的数据。因此,例如,如果您选择 aCar
并在Wheel
s 上加入,您将为每辆车返回四行,这并不是真正的问题。但是,如果您加入Wheels
和Seats
,您将获得 4 座汽车的 16 排座位。这种加入创建了笛卡尔积,因此在这种情况下可能需要进行第二次查询以获取座位,除非您只会选择几辆车。
要解决使用 Spring JDBC 加入时重写映射代码的问题,请考虑拆分 RowMappers。免责声明:我主要使用 Hibernate,对 Spring 的 JdbcTemplate 不太熟悉,尽管我已经使用了一些。让我举一个一对一连接的例子:
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_
以与共享映射器兼容。这不是一个理想的解决方案,但可以让您避免到处都有重复的映射代码。
对于一对多关联,您需要使用 aResultSetExtractor
因为一次RowMappers
只处理一行,并且会Cars
为每个Wheel
. 不过,方法是相同的,RowMappers
在适当的地方重用。
如果由于数据模型和业务逻辑往往需要它们而最终大量使用复杂的连接,并且您发现映射器的创建很尴尬,那么您可能会考虑使用 ORM 解决方案来为您处理映射。再说一次,如果你没有真正看到不使用连接的任何性能问题,你最好很少使用它们并坚持 JdbcTemplate 的简单性。