我正在编写一个用于培训目的的小工具 主要范围是了解如何在不使用ORM工具的情况下处理持久数据 所以,有一个带表的小DB:
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个实体:User,Role,Group 问题是:用关系来实现工作的最佳方式是什么? 如何在UserDAO,GroupDAO,RoleDAO之间共享相同的连接以使用数据库事务?
答案 0 :(得分:2)
一种选择是让服务启动JTA事务。这将自动可用于在同一线程中运行的所有代码。然后使用托管连接池,以便连接自动加入正在运行的JTA事务。
您可以在连接上执行常规的JDBC工作,只是不要在它们上面调用commit()
,而是在它们上面调用close()
。
如果您的目标只是了解持久性,并且此时您不一定想要考虑事务,则可以使用无状态会话Bean(EJB bean)。这些将自动启动并为您提交事务。该服务可以是您的客户端将调用的EJB,并且该服务将自动启动该事务。您的DAO也可以是无状态会话bean,并且可以注入数据源。
e.g。
@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
}
}
答案 1 :(得分:1)
让DAO共享连接很容易,因为它应该由服务层创建,传递到每个DAO对象并关闭。只需通过连接。
另一种选择是不共享三个DAO之间的连接。您可以进行一次JOIN查询,将所有数据一次性恢复,并将其映射到对象中,而不是进行三次查询。线路上的惩罚是更多的字节,因为您为每个子对象带回了父数据。
答案 2 :(得分:1)
使用本地线程来保存对连接的引用。传递连接时,DAO将使用服务层的连接。当调用者(服务层)没有通过连接时,DAO将使用来自thread-local的连接。因此,所有DAO都可以在给定的线程中共享相同的连接。
TX管理如下。
所有交易都在服务层启动和结束。 DAO不会有任何提交/回滚逻辑。由于连接是在所有DAO之间共享的,因此调用者(服务层)完全控制了事务。