使用JDBC DAO实现ORM的多对一和多对多关系

3

我正在编写一个小工具,用于培训目的。
主要目的是了解如何在不使用ORM工具的情况下处理持久数据。
因此,有一个包含以下表格的小型数据库:

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之间共享相同的连接以使用DB事务?

3个回答

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
   }
}

我喜欢你的回答。你展示了在Java中持久性可以只有25行代码。 - kiran.kumar M
纯持久化部分可以降至6,因为客户端也可以直接使用UserDAO,因为它本身已经完全功能。说实话,对于数据源,您确实需要在try-finally或try-with-resources(JDK 7)块中关闭连接,这意味着需要两行额外的代码。当注入entityManager而不是数据源时,不需要关闭并且entityManager也可以执行纯SQL。 - Arjan Tijms

1

让DAO共享连接很容易,因为它应该由服务层创建,传递到每个DAO对象中并关闭。只需在DAO之间传递连接即可。

另一种选择是不在三个DAO之间共享连接。您可以进行一次JOIN查询,将所有数据一次性带回并映射到对象中,而不是进行三个查询。缺点是在网络上传输的字节数更多,因为您为每个子对象都带回了父数据。


1
使用线程本地变量来保存连接的引用。当传递了连接时,DAO将使用服务层中的连接。当调用者(服务层)没有传递连接时,DAO将使用线程本地的连接。因此,在给定的线程中,所有DAO都可以共享同一个连接。
TX管理如下。
所有事务都在服务层启动和结束。DAO不会有任何提交/回滚逻辑。由于连接在所有DAO之间共享,所以调用者(服务层)完全控制事务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接