代码之家  ›  专栏  ›  技术社区  ›  Paul Hanbury

Spring框架JDBC-DAO与aggregation/composition

  •  4
  • Paul Hanbury  · 技术社区  · 14 年前

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

    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和accountdao共享同一个数据源实例(在我们的例子中这是一个连接池),任何数据库访问都是通过不同的连接完成的。

    如果对象层次结构甚至有三层深,那么使用此实现将导致 (2) 更糟糕的是,由于我们限制了连接池中允许的连接数,因此当多个线程试图从数据库加载项目时,可能会出现争用情况。

    Spring中有没有更好的方法(没有其他成熟的ORM工具)来加载这样的对象层次结构?

    1 回复  |  直到 14 年前
        1
  •  2
  •   mdma    14 年前

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

    例如,您可以构建一个自定义列表类型,该类型接受一个id列表和一个DAO实现。该列表仅由ProjectRowMapper中的id填充,并分配给项目的accounts属性。ID对列表是私有的—它们不是列表的“内容”,而是以后生成真实内容的一种方法。