Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MyBatis使用单个映射器提供多个数据源_Java_Guice_Mybatis - Fatal编程技术网

Java MyBatis使用单个映射器提供多个数据源

Java MyBatis使用单个映射器提供多个数据源,java,guice,mybatis,Java,Guice,Mybatis,我正在开发一个系统,该系统使用guice绑定和注入MyBatis映射器,用于从不同的数据库中删除条目。事实上,所有数据库都位于不同的主机中,但具有相同的结构。因为有很多,而且主机的数量和位置经常变化,所以我想安装一个MyBatis模块,其中包含使用同一映射器动态加载的不同数据源 我一直在四处寻找,但不知道如何解决映射器的模糊性。我还查看了MyBatis beans CDI插件,它使添加具有多个数据源的命名映射器变得更容易,但仍然无法使其工作,因为我没有可以命名的固定数据源列表 我是否缺少一种简单

我正在开发一个系统,该系统使用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
中添加+expose
SomeMapperForDbA

这里的接口名充当逻辑数据源鉴别器,而所有映射查询仍然保持在
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 {}