在日常开发中我们可能会用到多数据源开发,什么是多数据源?
简单来讲的话,就是一个项目连接多个数据库。当然只是可能会用到,我暂时没见过应用场景,但是还是了解学习一下
此项目可以基于上一个简单集成项目进行简单的修改,就能实现多数据源了。
application.yml配置
我们在上一个项目的基础上进行修改,实现多数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
one:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
initialSize: 5
minIdle: 5
maxActive: 20
initial-size: 3
min-idle: 3
max-active: 10
max-wait: 60000
two:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/layui?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
initialSize: 5
minIdle: 5
maxActive: 20
initial-size: 6
min-idle: 6
max-active: 20
max-wait: 12000
stat-view-servlet:
login-username: admin
login-password: admin
filter:
stat:
log-slow-sql: true
slow-sql-millis: 2000
mybatis:
mapper-locations: classpath:mappers///Mapper.xml
type-aliases-package: com.ccsert.spdruid..model
configuration:
map-underscore-to-camel-case: true
logging:
file: logs/mass.log
level:
org.springframework: info
com.ccsert: DEBUG
着是完整的配置
主要在druid数据源和mybatis的mapper.xml进行了细微修改
这里我建立一个layui数据库,里面有个和demo里一样的表,数据和结构都一样,方便等会测试
包结构调整,代码修改
包结构调整
我们先把mapper接口修改一下
在原来的mapper包下建立两个包,一个one,一个two
然后把之前的mapper接口分别复制到one和two下
然后改一下名字
改完以后大概就是这个样子
代码修改
把之前的mapper注解都去掉
后面会用别的方法去映射
这是oneMapper
package com.ccsert.spdruid.test.mapper.one;
import com.ccsert.spdruid.test.model.TestUser;
import java.util.List;
public interface TestUserOneMapper {
List getall();
TestUser getById(Integer id);
int save(TestUser testUser);
}
这是twoMapper
package com.ccsert.spdruid.test.mapper.two;
import com.ccsert.spdruid.test.model.TestUser;
public interface TestUserTwoMapper {
TestUser getById(Integer id);
}
这里为了方便我就只写一个接口
然后我们在修改一下service实现类
package com.ccsert.spdruid.test.service.impl;
import com.ccsert.spdruid.test.mapper.one.TestUserOneMapper;
import com.ccsert.spdruid.test.mapper.two.TestUserTwoMapper;
import com.ccsert.spdruid.test.model.TestUser;
import com.ccsert.spdruid.test.service.TestUserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class TestUserServiceImpl implements TestUserService {
@Resource
private TestUserOneMapper testUserOneMapper;
@Resource
private TestUserTwoMapper testUserTwoMapper;
@Override
public List getall() {
return testUserOneMapper.getall();
}
@Override
public TestUser getById(Integer id) {
return testUserTwoMapper.getById(id);
}
@Override
public int save(TestUser testUser) {
return testUserOneMapper.save(testUser);
}
}
getById方法让他去调用twoMapper
其余的还是让它去调用原来的接口
配置文件修改
然后我们把xml的位置移动一下
在resources下的mappers下在建立两个文件夹
一个one
一个two
然后在把之前的TestUser目录复制两份到one和two下
把原来的TestUser删除掉
在把之前的xml名字修改一下
改完以后大概就是这个样子了
onemapper.xml的内容保持不变
主要写一下twomapper.xml的save保存方法
SELECT
id,user_name,password
FROM
test_user
WHERE id=#{id}
因为这里的mapper接口路径是修改过的,onemapper.xml要注意一下
多数据源配置
准备工作做好了接着就是配置多数据源了
在test包下建立一个config包,用于存放配置
然后在config包下建立一个MultiDataSourceConfig类
package com.ccsert.spdruid.test.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
@Configuration
public class MultiDataSourceConfig {
@Primary
@Bean(name = "oneDataSource")
@ConfigurationProperties("spring.datasource.druid.one")
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "twoDataSource")
@ConfigurationProperties("spring.datasource.druid.two")
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
}
这里的ConfigurationProperties是获取的yml或者properties里的值
spring.datasource.druid.one和spring.datasource.druid.two就是我们配置的数据源
Primary只能指定一个为默认数据源,这里指定了one数据库
在config下建立DataSource1Config类,用于配置数据源one
package com.ccsert.spdruid.test.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.ccsert.spdruid.test.mapper.one", sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSource1Config {
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/one/**/*Mapper.xml"));
return bean.getObject();
}
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
@MapperScan(basePackages = "com.ccsert.spdruid.test.mapper.one", sqlSessionTemplateRef = "test1SqlSessionTemplate")指定了实体类的路径,这里就完成了映射,所以不需要在mapper接口上写@Mapper注解
然后在建立一个DataSource2Config类
内容和上面的差不多
package com.ccsert.spdruid.test.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.ccsert.spdruid.test.mapper.two", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DataSource2Config {
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/two/**/*Mapper.xml"));
return bean.getObject();
}
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意这两个路径写成自己的不要搞错了
到这里就配置完成了
测试使用
我们先访问一下接口能否调通
启动项目然后使用谷歌插件访问接口
可以看到我们两个接口都调用成功
我们去druid的监控界面查看一下执行的sql和数据源信息
可以看到druid监控了我们执行的两条sql,以及两个数据源信息