MyBatis,根据环境动态改变数据库类型

MyBatis, change Database type dinamically based on the environment

我有一个基于 REST 的 java Web 应用程序 Java 8,MyBatis 3.4.5,部署在 Wildfly 应用程序服务器上。 在这个应用程序中,我有一个 DB jar 模块,它管理所有查询、连接、对象...from/to application/DB。我所有其他必须与数据库交互的 Java 代码(控制器、方法、类)都使用这个数据库模块。

作为标准的 MyBatis 实现,我在 DB 模块中有这些包

类 和 xml 文件的内容根据底层数据库类型(PostgreSQL、Oracle)而变化,因为数据库语法、数据库数据类型等不同。

当我需要查询数据库时,我有这样的东西:

my.app.oj.db.manager.UserManager userManager = new  my.app.oj.db.manager.UserManager();
List<my.app.oj.db.model.User> users = userManager.selectAllUsers();

基本上我的管理器包定义了如何进行查询

在一个环境中,我使用 PostgreSQL 作为数据库。 我的 myBatis 配置文件是:

<configuration>
<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC" />
        <dataSource type="POOLED">
            <property name="poolMaximumActiveConnections" value="15" />
            <property name="driver" value="${posgresValue}" />
            <property name="url" value="${url} />
            <property name="username" value="${username}" />
            <property name="password" value="${password}" />
        </dataSource>
    </environment>
</environments>
<mappers>
    <package name="my/app/oj/db/mapper/" />
</mappers>
</configuration>

现在我必须添加另一个环境,它使用 Oracle 作为数据库,所以它会有不同的连接 url、用户名和密码,而且,最重要的是,它会有不同映射器,java 和 xml 文件。我不需要同时连接到这些数据库,但我必须根据我部署应用程序的环境选择其中之一。

使用不同的 db-data-config.xml 文件我将根据环境设置连接属性和 Mappers.xml,但是如何更改 java 类 被称为 ?

我知道我可以复制我项目的所有数据库模块并在 build/deploy 阶段更改它,但我需要保持它的单一性,并区分包。

我想获得这样的东西

并在未来添加一些其他数据库支持,如 MySql 等等... 因此,当我查询数据库时,java 管理器将根据我的需要进行更改。

my.app.oj.db.<PostgreSQL>.manager.UserManager userManager = new  my.app.oj.db.<PostgreSQL>.manager.UserManager();
List<my.app.oj.db.<PostgreSQL>.model.User> users = userManager.selectAllUsers();

我怎样才能得到这个?我找不到让 MyBatis 处理这个问题的方法,也许这不是 "ORM" 问题,而是 java 模式。

感谢大家。

你是对的,这不是ORM的问题。

UserManager 的客户端应与特定类型的 DB 隔离,并动态获取正确的 UserManager 实现,如下所示:

DBType dbType = DBType.POSTGRESQL; // DBType is the enum
my.app.oj.db.common.manager.UserManager userManager = my.app.oj.db.common.manager.UserManagerFactory.getManager(dbType);
List<my.app.oj.db.common.model.User> users = userManager.selectAllUsers();

请注意,客户端代码不知道 UserManagerUser 的特定类型。它通过使用 common 类型来工作,这些类型是为特定数据库实现的接口。

您要么需要一个由所有实现共享的 User 模型,要么您将需要一个所有模型都将实现的接口,如下所示:

my/app/oj/db/common/model/User.java:

interface User {
  String getName();
  ...
}

然后是用户管理界面:

my/app/oj/db/common/manager/UserManager.java:

interface UserManager {
  List<my.app.oj.db.common.model.User> selectAllUsers();
}

现在针对 postgres 的特定用户管理器的实现例如:

my/app/oj/db/postgres/manager/UserManager.java:

class UserManager implements my.app.oj.db.common.manager.UserManager {
   public List<my.app.oj.db.common.model.User> selectAllUsers() {
     // uses postgres specific mappers to return
     // list containing instances of my.app.oj.db.common.postgres.model.User if
     // you used db specific model implementation
   }
}

最后 UserManagerFactory:

class UserManagerFactory {
   my.app.oj.db.common.manager.UserManager getManager(DBType dbType) {
    switch (dbType) {
      case DBType.POSTGRES:
        return new my.app.oj.db.postgres.manager.UserManager();
      case DBType.ORACLE:
        return new my.app.oj.db.oracle.manager.UserManager(); 
   } 
}