0

我有一个通用的设计问题困扰了我一段时间。

目标:

  • 使用 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 传递给多个类并不好。

您将采取什么方法来实现所述目标?

如果有人可以提供帮助,我将不胜感激。如果您需要更多信息,请告诉我,我会提供!

4

1 回答 1

0

您是否对需求和解决方案感到困惑?

每个项目的数据必须分开(到不同的数据库中)

是否真的要求您拥有不同的数据库,或者只是每个项目的数据必须分开

如果不同的数据库不是绝对要求,只需user_id在足够多的表中添加一列,这样您就可以为所有用户使用相同的表,但仍然可以满足此要求。

您可以将这种方法称为垂直分区数据,而不是水平分区。

好处应该是显而易见的:突然间,您的解决方案变得简单了很多,这是一件好事。

于 2011-06-16T03:59:29.353 回答