在一些大型的项目中,通常会选择多数据库来满足一些业务需求,此处讲解使用springboot、mybatis和druid来配置多数据源
1、依赖配置
pom文件引入相关依赖
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
application文件加入多数据源配置
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: # 主库数据源 master: url: jdbc:mysql://localhost:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false username: root password: root # 从库数据源 slave: url: jdbc:mysql://ip:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false username: root password: root # 初始连接数 initial-size: 10 # 最大连接池数量 max-active: 100 # 最小连接池数量 min-idle: 10 # 配置获取连接等待超时的时间 max-wait: 60000 # 打开PSCache,并且指定每个连接上PSCache的大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 min-evictable-idle-time-millis: 300000 validation-query: SELECT 1 FROM DUAL test-while-idle: true test-on-borrow: false test-on-return: false stat-view-servlet: enabled: true url-pattern: /monitor/druid/* filter: stat: log-slow-sql: true slow-sql-millis: 1000 merge-sql: false wall: config: multi-statement-allow: true
2、添加主数据源和其他数据源配置
主数据源
@Configuration //master mapper目录 @MapperScan(basePackages = {"com.example.springbootdruidmultsource.mapper.master"}, sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDataSourcesConfig { private static final String MAPPER_LOCAL = "classpath:mybatis/master/*.xml"; @ConfigurationProperties("spring.datasource.druid.master") @Primary @Bean(name = "masterDataSource") public DruidDataSource druidDataSource() { return new DruidDataSource(); } @Bean(name = "masterTransactionManager") @Primary public DataSourceTransactionManager masterTransactionManager() { return new DataSourceTransactionManager(druidDataSource()); } @Bean(name = "masterSqlSessionFactory") @Primary public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception { final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL)); return sessionFactoryBean.getObject(); } }
其中注解@Primary表示是主数据源
从数据源
@Configuration @MapperScan(basePackages = {"com.example.springbootdruidmultsource.mapper.slave"}, sqlSessionFactoryRef = "slaveSqlSessionFactory") public class SlaveDataSourcesConfig { private static final String MAPPER_LOCAL = "classpath:mybatis/slave/*.xml"; @Bean(name = "slaveDataSource") @ConfigurationProperties("spring.datasource.druid.slave") public DruidDataSource druidDataSource() { return new DruidDataSource(); }
//其他数据源的事务管理器 @Bean(name = "slaveTransactionManager") public DataSourceTransactionManager slaveTransactionManager() { return new DataSourceTransactionManager(druidDataSource()); } @Bean(name = "slaveSqlSessionFactory") public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DruidDataSource dataSource) throws Exception { final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL)); return sessionFactoryBean.getObject(); } }
其他的就是mybatis相关的一些内容,这里不赘述
3、事务管理
对主数据原来说,直接在注解
@Override @Transactional public void update(SysUser sysUser) { sysUserMapper.update(sysUser); int i = 10 / 0; }
对其他数据源来说,需要加上配置的事务管理器
@Override @Transactional(value = "slaveTransactionManager") public void update(User user) { userMapper.update(user); int i = 10 / 0; }