MyBatis-guice 3.3 + Múltiplas fonts de dados + propriedades + scriptrunner

Eu estou usando MyBatis-guice 3.3 para se conectar a um primeiro database usando um object de propriedades de java e um ScriptRunner para executar alguns scripts:

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"))); 

Agora eu gostaria de adicionar uma segunda fonte de dados (dbB) usando a mesma abordagem. Seguindo o guia de referência do MyBatis-guice, eu tenho que usar 2 PrivateModule. Esta parte funciona bem.

Mas como devo chamar meu ScriptRunner para executar alguns scripts para dbA e alguns outros para dbB?

Crie 2 annotations de qualificador @DbA e @DbB ou similar.

Agora cada um dos módulos privados irá chamar (via o MyBatisModule)

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

isso significa que não é possível fazer

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

que exigiria

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

Em vez disso, você precisa fornecer uma class intermediária que é injetada com SqlSessionFactory e é exposta com anotação de qualificador.

E em cada módulo privado fazer algo nas linhas de

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

Aqui está uma solução.

 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; } 

Se alguém está procurando uma solução no ambiente da plataforma GWT, aqui está a configuração de um ambiente de trabalho. Espero que isso seja útil.

 // 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()); } 
Intereting Posts