MyBatis-guice 3.3 +多个数据源+属性+ scriptrunner

我正在使用MyBatis-guice 3.3使用java Properties对象和ScriptRunner连接到第一个数据库来运行几个脚本:

Environment environment = injector.getInstance(SqlSessionFactory.class).getConfiguration().getEnvironment(); DataSource source = environment.getDataSource(); ScriptRunner runner = new ScriptRunner(source.getConnection()); runner.setLogWriter(null); runner.setStopOnError(true); runner.runScript(Resources.getResourceAsReader(properties.getProperty("script.dbA.create.schema"))); 

现在我想使用相同的方法添加第二个数据源(dbB)。 按照MyBatis-guice参考指南,我必须使用2个PrivateModule。 这部分工作正常。

但是,我应该如何调用我的ScriptRunner为dbA运行一些脚本,为dbB运行一些其他脚本?

创建2个限定符注释@DbA和@DbB或类似。

现在每个私有模块都会调用(通过MyBatisModule)

 binder().bind(SqlSessionFactory.class).toProvider(SqlSessionFactoryProvider.class).in(Scopes.SINGLETON); 

这意味着无法做到

 expose(SqlSessionFactory.class).annotatedWith(DbA.class); 

这需要

 binder().bind(SqlSessionFactory.class).annotatedWith(DbA.class).toProvider(SqlSessionFactoryProvider.class).in(Scopes.SINGLETON); 

相反,您需要提供一个使用SqlSessionFactory注入的中间类,并使用限定符注释公开。

并且在每个私有模块中做一些事情

 bind(MyBatisEnv.class).to(MyBatisImpl.class).annotatedWith(DbX.class); expose(MyBatisEnv.class).annotatedWith(DbX.class); 

这是一个解决方案。

 Injector injector = Guice.createInjector( new PrivateModule() { @Override protected void configure() { install(new MyBatisModule() { @Override protected void initialize() { bindDataSourceProviderType(BasicDataSourceProvider.class); bindTransactionFactoryType(JdbcTransactionFactory.class); // add all your mappers here nowhere else addMapperClass(MapperA1.class); } }); Names.bindProperties(binder(), createProperties("dbA")); // expose all your mappers here expose(MapperA1.class); // bind&expose all db specific stuff here (SessionFactory, SessionManager, etc.) bind(SqlSessionFactory.class).annotatedWith(DbA.class).to(SqlSessionFactory.class); expose(SqlSessionFactory.class).annotatedWith(DbA.class); }}, new PrivateModule() { @Override protected void configure() { install(new MyBatisModule() { @Override protected void initialize() { bindDataSourceProviderType(BasicDataSourceProvider.class); bindTransactionFactoryType(JdbcTransactionFactory.class); // add all your mappers here nowhere else addMapperClass(MapperB1.class); } }); Names.bindProperties(binder(), createProperties("dbB")); // expose all your mappers here expose(MapperB1.class); // bind&expose all db specific stuff here (SessionFactory, SessionManager, etc.) bind(SqlSessionFactory.class).annotatedWith(DbB.class).to(SqlSessionFactory.class); expose(SqlSessionFactory.class).annotatedWith(DbB.class); }} ); DataSource dbA dataSource = injector.getInstance(Key.get(SqlSessionFactory.class), DbA.class).getConfiguration().getEnvironment().getDataSource(); ScriptRunner runner = new ScriptRunner(source.getConnection()); runner.runScript(Resources.getResourceAsReader("dbA/path/create_db.sql")); runner.closeConnection(); private static Properties createDbProperties(String schema) { final Properties p = new Properties(); p.setProperty("mybatis.environment.id", "test"); p.setProperty("JDBC.driver", "org.hsqldb.jdbcDriver"); p.setProperty("JDBC.url", "jdbc:hsqldb:mem" + schema + ";sql.syntax_ora=true"); p.setProperty("JDBC.username", "sa"); p.setProperty("JDBC.password", ""); return p; } 

如果有人在GWT平台环境中寻找解决方案,那么这是来自工作环境的配置。 希望这很有用。

 // mybatis-dbA-config.xml                         ... //dbA Dao implementation public class DbADaoImpl implements DbADao { @Inject @Named("DbA") private SqlSession sqlSession; public List listDbADomains() { return this.sqlSession.selectList("com.example.mapper.DomainAMapper.listDomainAs"); } ... //dbB Dao implementation public class DbBDaoImpl implements DbBDao { @Inject @Named("DbB") private SqlSession sqlSession; public List listDbBDomains() { return this.sqlSession.selectList("com.example.mapper.DomainBMapper.listDomainBs"); } ... // Service implementation public class MyServiceImpl implements MyService { @Inject private DbADao aDao; @Inject private DbBDao bDao; @Transactional(isolation = Isolation.SERIALIZABLE) @Override public Boolean doBusinessStuff() { // use aDao. // use bDao. } ... // DbA Module public class DbAModule extends PrivateModule { @Override protected void configure() { install(new XMLMyBatisModule() { @Override protected void initialize() { setEnvironmentId("test"); setClassPathResource("mybatis-dbA-config.xml"); useJdbcDriverClassLoaderoracle.jdbc.OracleDriver.class.getClassLoader()); addProperties(createTestProperties()); } }); bind(SqlSession.class).annotatedWith(Names.named("DbA")).toProvider(SqlSessionManagerProvider.class).in(Scopes.SINGLETON); expose(SqlSession.class).annotatedWith(Names.named("DbA")); } protected static Properties createTestProperties() { final Properties myBatisProperties = new Properties(); myBatisProperties.setProperty("mybatis.environment.id", "test"); myBatisProperties.setProperty("JDBC.autoCommit", "false"); return myBatisProperties; } } ... // DbB Module // identical to the above replacing DbA with DbB ... // // GWTP Configurations // // public class DaoServiceModule extends AbstractModule { @Override protected void configure() { bind(Service.class).to(ServiceImpl.class); bind(DbADao.class).to(DbADaoImpl.class); bind(DbBDao.class).to(DbBDaoImpl.class); } public class GuiceServletConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new ServerModule(), new DispatchServletModule(), new DbAModule(), new DbAModule(), new DaoServiceModule()); }