Spring Framework JDBC DAO具有agrgegation / composition

我有一个应用程序已经使用Spring Framework和Spring JDBC使用SimpleJdbcTemplate和RowMapper类的DAO层。 这似乎与从数据库中读取的小类结构非常有效。 但是,我们需要加载包含其他对象集合的对象,这些对象仍然保存其他对象的集合。

这个问题的“显而易见的”解决方案是创建一个命名的RowMapper类或我们的对象,并将引用传递给构造函数中的正确DAO对象。 例如:

public class ProjectRowMapper implements ParameterizedRowMapper { public ProjectRowMapper(AccountDAO accountDAO, ) { this.accountDAO = accountDAO; } public Project mapRow(ResultSet rs, int rowNum) throws SQLException { Project project= new Project (); project.setProjecttId( rs.getString("project_id") ); project.setStartDate( rs.getDate("start_date") ); // project.setEtcetera(...); // this is where the problems start project.setAccounts( accountDAO.getAccountsOnProject(project.getProjectId()) ); } } 

问题是即使ProjectDAO和Account DAO共享相同的DataSource实例(在我们的例子中这是一个连接池),任何数据库访问都是通过不同的连接完成的。

如果对象层次结构甚至是三级深度,则使用此实现会导致(a)框架对datasource.getConnection()的多次调用,以及(2)更糟糕的是,因为我们限制了连接池中允许的连接数,multithreading尝试从数据库加载项目时潜在的竞争条件。

Spring中是否有更好的方法(没有另一个完整的ORM工具)来实现这种对象层次结构的加载?

谢谢,保罗

我猜你有理由不使用ORM,这是解决这类问题的理想工具。

多个连接的问题是对另一个DAO的递归调用。 为避免消耗其他连接,应在获取项目实例后稍后检索Account对象。 在获取项目时,也会获取accountID,但不会将其“实例化”到帐户实例 – 它们仍然是ID列表,然后在项目DAO完成工作后填充这些ID。

例如,您可以构建一个自定义List类型,该类型包含ID列表和DAO实现。 该列表仅使用ProjectRowMapper中的ID填充并分配给项目的accounts属性。 ID是列表专用的 – 它们不是列表的“内容”,而是稍后生成实际内容的方法。

一旦Project DAO从RowMapper中获取了项目,它就可以指示列表然后获取列表中保存的ID的帐户。 帐户被取为非嵌套操作,因此整个过程只使用一个连接。 然而,fetch是在DAO方法的范围内完成的,所以fetch是热切地完成的 – 因此没有懒惰加载问题需要处理。