2011-05-29 65 views
3

我正在寫一個用於培訓目的的小工具。
主要範圍是瞭解如何使用持久數據而不使用ORM工具。
所以,有一個小DB與表:使用JDBC的ORM多對一和多對多關係DAO

users(id, login, password, group_id) 
groups(id, name, description) 
roles(id, name, description) 
// for many-to-many relationship between groups and roles. 
groupsroles(group_id, role_id) 

所以,我實現了一個DAO模式,用3個實體:用戶,角色,組。
問題是:用關係來實現工作的最佳方式是什麼?
如何共享UserDAO,GroupDAO,RoleDAO之間使用數據庫事務的相同連接?

回答

1

很容易讓DAO共享連接,因爲它應該由服務層創建,傳入每個DAO對象並關閉。只需通過連接。

另一種選擇是不共享三個DAO之間的連接。您可以創建一個JOIN查詢,並將所有數據立即帶回並映射到對象中,而不是三個查詢。線上的懲罰是更多的字節,因爲你爲每個子對象帶回父數據。

1

使用本地線程來保存對連接的引用。當連接通過時,DAO將使用來自服務層的連接。當調用者(服務層)不傳遞連接時,DAO將使用來自線程本地的連接。因此,所有的DAO可以在給定的線程中共享相同的連接。

TX管理如下。

所有事務都在服務層啓動並結束。 DAO不會有任何提交/回滾邏輯。由於連接在所有DAO中共享,調用者(服務層)完全控制事務。

2

一種選擇是讓服務啓動JTA事務。這將自動適用於在同一個線程中運行的所有代碼。然後使用受管連接池,這樣連接會自動加入正在運行的JTA事務。

你可以在連接上做你平常的JDBC工作,只是不要打電話給他們commit(),但他們打電話給close()

如果您的目標僅僅是瞭解持久性,而您現在不一定想要考慮事務,那麼可以使用無狀態會話bean(EJB bean)。這些將自動啓動併爲您提交交易。服務可以是您的客戶將要調用的EJB,並且該服務將自動啓動事務。你的DAO也可以是無狀態會話bean,並且可以注入一個數據源。

例如

@Stateless 
public class MyService { 

    @EJB 
    private UserDAO userDAO; 

    @EJB 
    private GroupDAO groupDAO; 

    @EJB 
    private RoleDAO roleDAO; 

    public void myMethod() {  
     User user = userDAO.getById(...); 
     Group group = groupDAO.getByUserId(...); 
     // more DAO stuff 
    } 
} 

@Stateless 
public class UserDAO { 

    @Resource(mappedName="java:/myDS") 
    private DataSource dataSource; 

    public void getById(Long id) { 
     connection = dataSource.getConnection(); 
     // do JDBC work on connection 
    } 
} 
+0

我喜歡你的答案。你已經證明java中的持久性可以少至25行。 – 2011-05-29 14:27:27

+0

純粹的持久性部分可以降低到6,因爲客戶端也可以直接使用UserDAO,因爲它本身是完全功能的。說實話,對於數據源,您需要在try-finally或try-with-resources(JDK 7)塊中關閉連接,這意味着需要增加兩行。注入entityManager而不是數據源時,不需要關閉,entityManager也可以執行純SQL。 – 2011-05-29 15:20:44