我有一个通用的设计问题困扰了我一段时间。
目标:
- 使用 Vaadin 为前端创建 Web 应用程序
- 用户必须能够在运行时创建项目。每个项目都使用相同的(域)模型,但数据不同
- 每个项目的数据必须分开(到不同的数据库中)
- 用户可以登录,选择项目并访问特定的数据库
- 不同的用户可以同时处理不同的项目
- 应用程序使用带有注释和编程配置的 Hibernate
现在的情况
- 静态HibernateUtil在很多地方使用(getSessionFactory.getCurrentSession)
- 使用 ThreadLocal 部分实现 Session-Per-View 模式以获取当前的应用程序实例,该实例通过使用 HTTPServletRequestListener 在查看请求之前和之后打开和关闭会话和事务来充当会话(和事务)管理器
- 无法直接访问视图层的逻辑层:
- 在某些部分,当前会话是通过使用静态 HibernateUtil
- 在其他地方,通过构造函数设置会话管理器。然后将此会话管理器传递给 DAO 以提供用于数据检索的会话操作
- 创建项目时,使用 Hibernates 创建选项来创建数据库(将来可以在创建时切换为静态 ddl 导入)
问题
可以想象,存在各种问题:
- 静态访问 sessionfactory 以获取会话不适用于多个项目,因为静态 HibernateUtil 只能同时携带一个(db)url,因此会话会混合
- 从逻辑层访问 SessionManager 不好(需要通过几个构造函数来提供)
- 不同方法的混合是丑陋的,但目标是纠正这一点
想法
- 实现依赖注入,即使在逻辑层也能提供正确的 DAOFactory。用 Guice 尝试过,但如果实例不是通过注入器创建的,则会得到空指针异常(请参阅我的另一个问题)。因此它不起作用。
我希望我可以在代码中的任何位置注入/使用正确的 DAO 工厂实例(可以访问正确的会话/数据库),而无需逻辑层知道当前加载了哪个数据库。所以逻辑层不应该关心会话处理或任何事情。我只想从任何地方拨打 xyDAO.find(id) 或类似电话,它会获得正确的数据库。我还认为,如果只有逻辑深处的一个类需要它,那么通过构造函数将 SessionManager 传递给多个类并不好。
您将采取什么方法来实现所述目标?
如果有人可以提供帮助,我将不胜感激。如果您需要更多信息,请告诉我,我会提供!