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 模块中有这些包
- my/app/oj/db/客户端 包含负责翻译所有查询的所有java文件to/fromjava 对象 (UserMapper.java)
- my/app/oj/db/mapper 包含xml里面的所有查询(UserMapper.xml)
- my/app/oj/db/型号 型号包 (User.java )
- my/app/oj/db/管理器查询服务定义(UserManager.java)
类 和 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 阶段更改它,但我需要保持它的单一性,并区分包。
我想获得这样的东西
- my/app/oj/db/oracle/client
- my/app/oj/db/oracle/mapper
- my/app/oj/db/甲骨文/模型
- my/app/oj/db/oracle/管理器
- my/app/oj/db/postgres/客户端
- my/app/oj/db/postgres/mapper
- my/app/oj/db/postgres/模型
- my/app/oj/db/postgres/经理
并在未来添加一些其他数据库支持,如 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();
请注意,客户端代码不知道 UserManager
或 User
的特定类型。它通过使用 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();
}
}
我有一个基于 REST 的 java Web 应用程序 Java 8,MyBatis 3.4.5,部署在 Wildfly 应用程序服务器上。 在这个应用程序中,我有一个 DB jar 模块,它管理所有查询、连接、对象...from/to application/DB。我所有其他必须与数据库交互的 Java 代码(控制器、方法、类)都使用这个数据库模块。
作为标准的 MyBatis 实现,我在 DB 模块中有这些包
- my/app/oj/db/客户端 包含负责翻译所有查询的所有java文件to/fromjava 对象 (UserMapper.java)
- my/app/oj/db/mapper 包含xml里面的所有查询(UserMapper.xml)
- my/app/oj/db/型号 型号包 (User.java )
- my/app/oj/db/管理器查询服务定义(UserManager.java)
类 和 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 阶段更改它,但我需要保持它的单一性,并区分包。
我想获得这样的东西
- my/app/oj/db/oracle/client
- my/app/oj/db/oracle/mapper
- my/app/oj/db/甲骨文/模型
- my/app/oj/db/oracle/管理器
- my/app/oj/db/postgres/客户端
- my/app/oj/db/postgres/mapper
- my/app/oj/db/postgres/模型
- my/app/oj/db/postgres/经理
并在未来添加一些其他数据库支持,如 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();
请注意,客户端代码不知道 UserManager
或 User
的特定类型。它通过使用 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();
}
}