当前位置: 首页 > 知识库问答 >
问题:

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

穆景辉
2023-03-14

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

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

  • my/app/oj/db/client包含负责将所有查询转换到/从java对象(usermapper.java)的所有java文件
  • my/app/oj/db/mapper包含xml(usermapper.xml)中的所有查询
  • 我的/app/oj/db/model模型包(user.java)
  • 我的/app/oj/db/manager查询服务定义(usermanager.java)

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

当我需要查询DB时,我有如下所示:

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

所以基本上我的Manager包定义了查询是如何进行的

在一个环境中,我使用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作为db,因此它将具有不同的连接url、用户名和密码,最重要的是,它将具有不同的映射器,包括java和xml文件。我不需要同时连接到这些DB,但我必须根据我部署应用程序的环境选择其中一个。

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

我知道我可以复制项目的所有DB模块,并在构建/部署阶段对其进行更改,但我需要保持它的单一性,并区分包。

我想得到这样的东西

  • 我的/App/OJ/DB/Oracle/Client
  • My/App/OJ/DB/Oracle/Mapper
  • 我的/app/oj/db/Oracle/model
  • My/App/OJ/DB/Oracle/Manager
  • 我的/app/oj/db/postgres/client
  • 我的/app/oj/db/postgres/mapper
  • 我的/app/oj/db/postgres/model
  • 我的/app/oj/db/postgres/manager

并在未来添加一些其他数据库支持,如MySql等...因此,当我查询DB时,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”问题,而是一个javahtml" target="_blank">模式。

感谢所有人。

共有1个答案

杨安歌
2023-03-14

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

UserManager的客户端应该与特定类型的数据库隔离开来,并动态地获得正确的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类型来工作,这些类型是为特定DBS实现的接口。

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

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(); 
   } 
}
 类似资料:
  • 我正在尝试根据传递到作业中的参数在Jenkins管道作业中设置环境变量;这样,我可以在需要它的管道的每个阶段使用环境变量。我尝试在环境块中使用Switch语句: 然而,这并不起作用,该作业试图将等号之前的所有行评估为KEY名称: 我该如何让它工作?

  • 我的问题如下,我有一个Spring Boot应用程序,我使用Jooq for sql,我设置我的pom来生成表。数据库信息设置在环境变量中。它在Intellij内部运行良好,但当我生成。WAR并在客户端上上传应用程序只有当客户端库名与创建jooq代码时我pom.xml中的名称相同时,才有效。表完全一样,唯一可以改变的是库名,所以我在环境变量中查找名称信息。我的变量都设置在属性中,在调试中,我可以看

  • 问题内容: 我有一个项目,需要根据用户选择的选择参数设置环境变量。每个项目都有一个主题项目依赖项。我想让用户选择项目,然后从属性文件中加载主题名称。就像是 如果用户从choice参数中选择,我想自动设置为。最好的方法是什么? 每当添加新项目时,我都不想修改Jenkins作业配置。相反,我想将映射保存在文件中,以便可以在版本控制中使用它。 问题答案: 啊哈,我找到了一个简单的解决方案!使用EnvIn

  • 我正在做一个课程项目飞行雷达模拟器。 情况是,当两架飞机危险地接近时,两架飞机的图像都发生了变化,而当它们处于安全距离时,它们又发生了变化。 问题是,大多数时候,只有一个图像被改成红色,我不知道问题出在哪里。

  • 在 Angular 项目在实际运用中,我们需要静态文件放在 CDN 上。那怎么通过单一的 Docker image 实现 CDN 地址可变呢? 我们基于 用 Docker 搭建 Angular 前端应用 来做一些改进。 gulp 是一个很好用的构建工具,不仅是因为他的语法灵活,更是因为有非常多的插件供我们使用。 在这个例子中,我们使用 gulp-cdnizer。 Angular 项目构建优化 首先

  • 问题内容: 我正在尝试更改derby db列的数据类型。当前价格列设置为DECIMAL(5,0)。我想将其更改为DECIMAL(7,2)。我是这样做的: 但是它不起作用,并显示错误: 我可以知道如何进行更改吗?谢谢你。 问题答案: 这是Derby SQL脚本,用于将列MY_TABLE.MY_COLUMN从BLOB(255)更改为BLOB(2147483647):