Как настроить несколько источников данных MyBatis в Spring Boot?

С MyBatis-Spring-Boot-Starter мы можем легко интегрировать MyBatis с Spring Boot, он отлично работает для одного источника данных. Однако теперь мы хотели бы добавить дополнительный источник данных в наш проект, к сожалению, это кажется непростым. В официальной документации MyBatis я вижу следующее содержимое:

MyBatis-Spring-Boot-Starter будет:

  • Автоматическое определение существующего источника данных.
  • Создаст и зарегистрирует экземпляр SqlSessionFactoryBean, передавая этот источник данных в качестве входных данных.
  • Создаст и зарегистрирует экземпляр SqlSessionTemplate, полученный из SqlSessionFactoryBean.

Похоже, MyBatis-Spring-Boot-Starter на данный момент поддерживает только один источник данных. Итак, вопрос в том, как настроить несколько источников данных MyBatis в Sping Boot?


person derek.z    schedule 05.05.2016    source источник
comment
stackoverflow.com/questions/40743889/   -  person k19421    schedule 30.11.2016


Ответы (3)


Вы выделили 3 bean-компонента, которые необходимы для интеграции MyBatis+Spring. Они автоматически создаются для одного источника данных.

Если вам нужно два источника данных, вам нужно явно создать 3 bean-компонента для каждого источника данных. Итак, вы создадите 6 bean-компонентов (2 типа DataSource, 2 типа SqlSessionFactoryBean и 2 типа SqlSessionFactoryBean).

Чтобы связать DAO с определенным источником данных, вам нужно будет использовать sqlSessionTemplateRef или sqlSessionFactoryRef параметр аннотации @MapperScan.

Также я не рекомендую спускаться в ад XML. Я использовал его таким образом в PROD, с двумя источниками данных, без каких-либо уродливых XML-конфигов в различных проектах. Также были аннотированы SQL-запросы.

Позор в том, что документация MyBatis не очень хороша, и большинство примеров в XML.

person luboskrnac    schedule 05.05.2016
comment
спасибо за быстрый ответ, рекомендуется использовать параметры sqlSessionTemplateRef и sqlSessionFactoryRef аннотации @MapperScan, но я все еще надеюсь, что смогу придерживаться стиля автоконфигурации spring-boot - person derek.z; 06.05.2016
comment
Я считаю, что это невозможно, если у вас есть два источника данных. Автонастройка Spring Boot отлично работает с одним источником данных. Spring Boot в первую очередь нацелен на мир микросервисов, где наличие двух источников данных является антипаттерном. - person luboskrnac; 06.05.2016

Что-то вроде этого к вашей весне servlet.xml:

<bean id="db2dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName"><value>${db2.database.driver}</value></property>
            <property name="url"><value>${db2.database.url}</value></property>
            <property name="username"><value>${db2.database.username}</value></property>
            <property name="password"><value>${db2.database.password}</value></property>
            <property name="maxActive"><value>${db2.database.maxactiveconnections}</value></property>
            <property name="maxIdle"><value>${db2.database.idleconnections}</value></property>
            <property name="initialSize"><value>${db2.database.initialSize}</value></property>

    </bean>   

    <bean id="db2SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="db2dataSource" />
        <property name="configLocation" value="/WEB-INF/mybatis-config.xml"/>
     </bean>

     <bean id="db2Dao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="db2SqlSessionFactory"/> 
        <property name="mapperInterface" value="com.dao.db2Dao" />
    </bean> 

        <bean id="oracledataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName"><value>${oracle.database.driver}</value></property>
            <property name="url"><value>${oracle.database.url}</value></property>
            <property name="username"><value>${oracle.database.username}</value></property>
            <property name="password"><value>${oracle.database.password}</value></property>
            <property name="maxActive"><value>${oracle.database.maxactiveconnections}</value></property>
            <property name="maxIdle"><value>${oracle.database.idleconnections}</value></property>
            <property name="initialSize"><value>${oracle.database.initialSize}</value></property>

    </bean> 
    <bean id="oracleSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="oracledataSource" />
        <property name="configLocation" value="/WEB-INF/mybatis-config.xml"/>
     </bean>
     <bean id="oracleoardDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="oracleSqlSessionFactory"/>  
        <property name="mapperInterface" value="com.lodige.clcs.dao.oracleoardDao" />
    </bean> 
person SiddP    schedule 05.05.2016
comment
спасибо за своевременный ответ, но это не стиль весенней загрузки, одна из величайших магий весенней загрузки - автоконфигурация, я все еще пытаюсь использовать минимальную конфигурацию, чтобы заставить ее работать. - person derek.z; 06.05.2016

Может быть, это то, что вам нужно

@Configuration
@MapperScan(basePackages = "com.neo.mapper.test1", sqlSessionTemplateRef  = 
"test1SqlSessionTemplate")
public class DataSource1Config {

@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")
@Primary
public DataSource testDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean.getObject();
}

@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
    return new SqlSessionTemplate(sqlSessionFactory);
}
person Explicit    schedule 17.05.2019