我正在使用Spring JDBC,我想知道什么是最好的:加入所有表,以便我可以获得我想要填充的对象的所有关联或执行多个选择查询?当你需要加入一个表来获取对象的所有数据时,你如何处理Spring中表的连接?
答案 0 :(得分:1)
一般来说,最好加入尽可能多的表,就像从对象中引用一样。您带回的列数不太可能超过为数据的其余部分多次调用数据库的缺点。
唯一真正的例外是,如果您想要多对一关联的数据。因此,例如,如果您选择Car
并加入Wheel
,则每辆车将返回四行,这不是真正的问题。但是,如果您加入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
方法{1}}。如果你选择后者,你可能会有名称冲突,所以选择变量的别名可能是有序的。即便如此,如果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_
,因为ResultSetExtractor
一次只能处理一行,并且每{{1}都会给您重复RowMappers
}}。但方法是相同的,在适当的地方重用Cars
。
如果你最终使用复杂的连接因为你的数据模型和业务逻辑往往需要它们而你发现mappers的创建很尴尬,你可能会考虑一个ORM解决方案来处理你的映射。再说一次,如果你没有真正看到因为不使用连接而出现任何性能问题,那么最好不要再使用它们并坚持使用JdbcTemplate的简单性。