2010-06-21 45 views
4

我有一个应用程序已经使用Spring Framework和Spring JDBC以及使用SimpleJdbcTemplate和RowMapper类的DAO层。对于从数据库中读取的小型结构,这看起来工作得很好。但是,我们需要加载持有其他对象集合的对象,这些对象仍然保存着其他对象集合。Spring Framework JDBC DAO with agrrgation/composition

这个问题的“明显”解决方案是创建一个命名的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和帐户DAO共享相同的DataSource实例(在我们的例子,这是一个连接池),任何数据库访问都是通过不同的连接来完成。

如果对象层次甚至是三个层次深,由框架的DataSource.getConnection()使用 (一)多次调用该实施效果,并 (2)更糟糕,因为我们盖的连接数允许在我们的连接池中,潜在的竞争条件,而多线程正试图从数据库中加载项目。

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

感谢, 保罗

+1

完整的ORM工具正是您在这里所需要的。这些问题很难,不要重塑它们。 – skaffman 2010-06-21 13:41:50

+1

你的代码是否有任何交易?我们使用相同的嵌套dao模式来加载复杂的对象,但Spring JDBC只使用一个连接 – Serxipc 2010-11-19 09:21:43

回答

2

我猜你有没有使用ORM,这是这类问题的理想工具的原因。

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

例如,您可以构建一个自定义列表类型,其中包含ID和DAO实现的列表。该列表仅使用ProjectRowMapper中的ID填充并分配给项目的accounts属性。这些ID对于列表是私人的 - 它们不是列表的“内容”,而是一种稍后产生真实内容的手段。

一旦项目DAO从RowMapper中获取了项目,它就可以指示列表然后获取保存在列表中的ID的帐户。这些帐户是作为非嵌套操作获取的,因此整个过程在任何时候都只使用一个连接。然而,提取是在DAO方法的范围内完成的,因此提取是急切地完成的 - 所以没有需要处理的延迟加载问题。

+0

这就是我所做的,现在它工作得非常好。 – 2010-07-07 19:59:06