Java MyBatis使用单个映射器提供多个数据源
我正在开发一个系统,该系统使用guice绑定和注入MyBatis映射器,用于从不同的数据库中删除条目。事实上,所有数据库都位于不同的主机中,但具有相同的结构。因为有很多,而且主机的数量和位置经常变化,所以我想安装一个MyBatis模块,其中包含使用同一映射器动态加载的不同数据源 我一直在四处寻找,但不知道如何解决映射器的模糊性。我还查看了MyBatis beans CDI插件,它使添加具有多个数据源的命名映射器变得更容易,但仍然无法使其工作,因为我没有可以命名的固定数据源列表Java MyBatis使用单个映射器提供多个数据源,java,guice,mybatis,Java,Guice,Mybatis,我正在开发一个系统,该系统使用guice绑定和注入MyBatis映射器,用于从不同的数据库中删除条目。事实上,所有数据库都位于不同的主机中,但具有相同的结构。因为有很多,而且主机的数量和位置经常变化,所以我想安装一个MyBatis模块,其中包含使用同一映射器动态加载的不同数据源 我一直在四处寻找,但不知道如何解决映射器的模糊性。我还查看了MyBatis beans CDI插件,它使添加具有多个数据源的命名映射器变得更容易,但仍然无法使其工作,因为我没有可以命名的固定数据源列表 我是否缺少一种简单
我是否缺少一种简单的方法来实现这一点?您需要私下绑定MyBatisModule,并使用唯一的绑定属性公开映射。下面有一个例子。我也验证了它的有效性:) DaoModule:此模块设置为将单个映射器绑定到具有特定数据源的密钥。注意,这个类扩展了一个“PrivateModue”,它将密钥公开给父模块。您将使用此键注入映射
public class DaoModule<T> extends PrivateModule {
private static final String ENVIRONMENT_ID = "development";
private final Key<T> key;
private final Class<T> mapper;
private final Provider<DataSource> dataSourceProvider;
public DaoModule(Key<T> key, Class<T> mapper, Provider<DataSource> dataSourceProvider) {
this.key = key;
this.mapper = mapper;
this.dataSourceProvider = dataSourceProvider;
}
@Override
protected void configure() {
install(new InnerMyBatisModule());
expose(key);
}
private class InnerMyBatisModule extends MyBatisModule {
@Override
protected void initialize() {
bind(key).to(mapper);
addMapperClass(mapper);
environmentId(ENVIRONMENT_ID);
bindDataSourceProvider(dataSourceProvider);
bindTransactionFactoryType(JdbcTransactionFactory.class);
}
}
}
示例注入类:这显示了如何使用字段注入来注入映射器
public class MyExampleClass {
@Inject
@Named("Mapper1")
MapperDao mapper1;
@Inject
@Named("Mapper2")
MapperDao mapper2;
}
这个答案的范围与问题的范围略有不同。对于拥有固定数量数据源并需要共享映射器的任何人,还有一种解决方案,它不使用公认答案中描述的
@Named
你可以简单地使用
interface SomeMapperForDbA extends SomeMapper {}
并在相应的PrivateModule
中添加+exposeSomeMapperForDbA
这里的接口名充当逻辑数据源鉴别器,而所有映射查询仍然保持在SomeMapper
中的一个位置。与命名注入相比,这种方法有其优点和缺点,但它是有效的,可能会为某些人节省时间
显然,您需要注入SomeMapperForDbA
来使用DbA数据源。也就是说,它只能在构造函数中完成,而实际代码中使用的类成员类型只能是SomeMapper
,以避免混淆
或者,如果数据库有公共部分和不同部分等,您可以将一些特定于DbA的选择添加到someMapPerformDBA
。在这种情况下,我建议使用更好的名称,以反映这种逻辑
也就是说,在需要时不要害怕扩展映射器接口。org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource就是为此而设计的
谢谢,这真的很有帮助。我正在处理的上下文有点复杂,而且,在某一点上,实际将注入器放在那里变得有点困难。这就是为什么我尝试在所有映射器中使用MapBinder,而不是键绑定。这样,我可以检索所有映射器,而不需要injector对象本身,但它不工作。您知道是否可以这样做,或者密钥绑定是唯一的选项吗?谢谢again@AndreuMarimon您不需要使用喷油器。。。将值注入类时,只需使用“@Named”注释。我在答案中添加了MyExampleClass。我只是用注入器显示它是绑定在guice中的。问题是名称是在运行时生成的,所以我不知道会有多少个映射以及它们会有哪些名称。我最终通过创建自己的实现guice提供程序接口的提供程序解决了这个问题。在那里,我可以管理名称并直接从注入器获取实例。不完美,也不干净,但它可以工作。据我所知,MapBinder选项在当前版本的guice中仍然不可用。mapBinder不能由使用相同类的不同私有模块共享。我会继续找的,心想。谢谢你的解决方案!
public class MyExampleClass {
@Inject
@Named("Mapper1")
MapperDao mapper1;
@Inject
@Named("Mapper2")
MapperDao mapper2;
}
interface SomeMapperForDbA extends SomeMapper {}