2010-06-21 80 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