Mybatis Spring多个数据库Java配置

我正在使用Spring和Mybatis并且我有两个数据库,第一个数据库的配置相对容易,但我无法使用Spring和事务处理第二个数据库,这里是我的代码

@Configuration @ComponentScan(basePackages = {"hernandez.service", "hernandez.dao"}) @EnableTransactionManagement @MapperScan(basePackages="hernandez.mapper" ) @Import(DbConfig2.class) public class AppConfig { @Bean(name = "dataSource") public DataSource dataSource() { DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/northwind", "root", ""); return ds; } @Bean public SqlSessionFactoryBean sqlSessionFactory() { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource()); return factoryBean; } @Bean(name = "transactionManager") public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } } @Configuration @MapperScan("loli.mapper" ) public class DbConfig2 { @Bean(name = "dataSource_2") public DataSource dataSource2() { DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/dmsolut_dmsms", "root", ""); return ds; } @Bean public SqlSessionFactory sqlSessionFactory2() throws Exception{ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource2()); return factoryBean.getObject(); } @Bean(name = "transactionManager_2") public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource2()); } } 

有没有办法让这个使用纯Spring Java配置或至少使用一些XML? 没有官方文档可以让两个数据库在Mybatis-Spring项目中运行

mybatis的多数据源现在在我的项目中使用。 这是一个示例,添加到您的application.xml

                                         

使用我们在项目中使用的java配置示例添加答案:

 import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.type.JdbcType; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration @ComponentScan(basePackages = "com.mycompany") @EnableTransactionManagement(proxyTargetClass = true) public class ApplicationConfig2 { public static final String DATA_SOURCE_NAME_1 = "jdbc/dataSource1"; public static final String DATA_SOURCE_NAME_2 = "jdbc/dataSource2"; public static final String SQL_SESSION_FACTORY_NAME_1 = "sqlSessionFactory1"; public static final String SQL_SESSION_FACTORY_NAME_2 = "sqlSessionFactory2"; public static final String MAPPERS_PACKAGE_NAME_1 = "com.mycompany.mappers.dao1"; public static final String MAPPERS_PACKAGE_NAME_2 = "com.mycompany.mappers.dao2"; @Bean public DataSource dataSource1() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_1); } @Bean public DataSource dataSource2() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_2); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean(name = SQL_SESSION_FACTORY_NAME_1) public SqlSessionFactory sqlSessionFactory1(DataSource dataSource1) throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName()); sqlSessionFactoryBean.setDataSource(dataSource1); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject(); sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); return sqlSessionFactory; } @Bean(name = SQL_SESSION_FACTORY_NAME_2) public SqlSessionFactory sqlSessionFactory2(DataSource dataSource2) throws Exception { SqlSessionFactoryBean diSqlSessionFactoryBean = new SqlSessionFactoryBean(); diSqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName()); diSqlSessionFactoryBean.setDataSource(dataSource2); SqlSessionFactory sqlSessionFactory = diSqlSessionFactoryBean.getObject(); sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); return sqlSessionFactory; } @Bean public MapperScannerConfigurer mapperScannerConfigurer1() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage(MAPPERS_PACKAGE_NAME_1); configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_1); return configurer; } @Bean public MapperScannerConfigurer mapperScannerConfigurer2() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage(MAPPERS_PACKAGE_NAME_2); configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_2); return configurer; } } 

根据我的经验,您还应该将@Primary添加到其中一个DataSource bean中。 否则它将抛出NoUniqueBeanDefinitionException

 @Bean @Primary public DataSource dataSource1() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_1); } @Bean public DataSource dataSource2() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_2); } 

您可以通过扩展它并覆盖方法determineCurrentLookupKey()来使用spring的AbstractRoutingDataSource 。

弹簧配置

您可以在spring配置中定义单独的datasource

                 

将数据源与客户关联:

             

Java的

 package com.example; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class CustomerRoutingDataSource extends AbstractRoutingDataSource { @Bean CustomerContextHolder context; @Override protected Object determineCurrentLookupKey() { return context.getCustomerType(); } } 

基本上,每个请求都有其上下文。 您可以使用映射密钥将datasource与请求相关联。 您可以在此处找到dynamic-datasource-routing更多详细信息

    classpath:com/dtcc/dao/impl/DaoSqlMapConfig_MyBatis1.xml                  

如上所述,我们需要在DaoImpl中给出相应的sessionFactory。 如果您有多个sessionFactory,则无法在DaoImpl类中自动assemblySqlSessionTemplate。 为每个会话工厂指定唯一名称,并将其映射到相应的DaoImpl类。 您所要做的就是在DaoImpl类中使用Setter方法为SqlSessionTemplate创建对象,您可以使用sqlSessionTemplate对象进行db调用,如下所示:this.sqlSessionTemplate.selectList(“ProcedureID”,参数);