Spring Framework JDBC DAO具有agrgegation / composition

时间:2010-06-21 13:39:49

标签: java spring jdbc

我有一个应用程序已经使用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和帐户DAO共享相同的DataSource实例(在我们的例子中这是一个连接池),任何数据库访问都是通过不同的连接完成的。

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

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

谢谢, 保罗

1 个答案:

答案 0 :(得分:2)

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

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

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

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