【问题标题】:Spring Framework JDBC DAO with agrgegation/composition具有聚合/组合的 Spring Framework JDBC DAO
【发布时间】:2010-06-21 13:39:49
【问题描述】:

我有一个应用程序已经在使用 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) 更糟糕的是,由于我们限制了连接池中允许的连接数,当多个线程尝试从数据库加载项目时,可能会出现竞争条件。

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

谢谢, 保罗

【问题讨论】:

  • 一个成熟的 ORM 工具正是您所需要的。这些问题很难,不要重新发明它们。
  • 您的代码周围有交易吗?我们使用相同的嵌套 dao 模式来加载复杂对象,但 Spring JDBC 只使用一个连接

标签: java spring jdbc


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2013-05-09
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多