3

我正在使用 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 运行一些其他脚本呢?

4

3 回答 3

1

这是一个解决方案。

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;
}
于 2013-05-30T12:21:36.997 回答
1

创建 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);
于 2013-05-28T13:11:03.577 回答
1

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

// mybatis-dbA-config.xml
<configuration>

  <settings>
    <setting name="cacheEnabled" value="false" />
    <setting name="useGeneratedKeys" value="true" />
    <setting name="defaultExecutorType" value="REUSE" />
  </settings>

  <typeAliases>
    <package name="com.example.domain" />
  </typeAliases>

  <environments default="test">
    <environment id="test">
      <transactionManager type="JDBC" />
      <dataSource type="POOLED">
        <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@//localhost:1521/SchemaName" />
        <property name="username" value="user" />
        <property name="password" value="pwd" />
      </dataSource>
    </environment>
  </environments>

  <mappers>
    <mapper resource="com/example/mapper/DomainAMapper.xml" />
  </mappers>

</configuration>

...

//dbA Dao implementation
public class DbADaoImpl implements DbADao {
    @Inject
    @Named("DbA")
    private SqlSession sqlSession;

    public List<DomainA> 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<DomainB> 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());
  }
于 2014-01-13T17:59:54.513 回答