<connectionStrings>
<add name="test1" connectionString="server=127.0.0.1;user id=root;password=123456;database=db1;charset=utf8" providerName="MySql.Data.MySqlClient" />
<add name="test2" connectionString="server=127.0.0.1;user id=root;password=123456;database=db2;charset=utf8" providerName="MySql.Data.MySqlClient" />
<add name="test3" connectionString="server=127.0.0.1;user id=root;password=123456;database=db3;charset=utf8" providerName="MySql.Data.MySqlClient" />
<connectionStrings>
能不能像c#这样根据连接名称就自动选择呢,笔者的连接配置如下所示:
spring:
application:
name: csg-auth
datasource:
kbase:
- driverClassName: com.kbase.jdbc.Driver
jdbcUrl: jdbc:kbase://127.0.0.1
username: DBOWN
password:
jdbc:
- driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/nacos?serverTimezone=GMT%2B8&useUnicode=false&characterEncoding=utf8&useSSL=false
username: root
password: 123456
connName: nacos
- driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/tpi?serverTimezone=GMT%2B8&useUnicode=false&characterEncoding=utf8&useSSL=false
username: root
password: 123456
connName: tpi
其中kbase不用理会,是我们公司自己的数据库,jdbc是维护的连接集合,其中connName就是我们自定义的连接名称,
根据connName就可以自动切换到对应数据源。
第一步
/**
* 动态数据源
* */
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceHolder.getDataSource();
}
}
第二步
public class DataSourceHolder {
/**
* 线程本地环境
*/
private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();
/**
* 设置数据源
*/
public static void setDataSources(String connName) {
dataSources.set(connName);
}
/**
* 获取数据源
*/
public static String getDataSource() {
return dataSources.get();
}
/**
* 清楚数据源
*/
public static void clearDataSource() {
dataSources.remove();
}
}
第三步
@Component
@ConfigurationProperties("spring.datasource")
public class DataSourceConfig {
private List<DataSourceModel> jdbc;
public Map<Object, Object> getDataSourceMap(){
Map<Object, Object>map=new HashMap<>();
if (jdbc!=null&&jdbc.size()>0){
for (int i = 0; i < jdbc.size() ; i++) {
DataSourceBuilder dataSourceBuilder=DataSourceBuilder.create();
dataSourceBuilder.driverClassName(jdbc.get(i).getDriverClassName());
dataSourceBuilder.password(jdbc.get(i).getPassword());
dataSourceBuilder.username(jdbc.get(i).getUsername());
dataSourceBuilder.url(jdbc.get(i).getJdbcUrl());
map.put(jdbc.get(i).getConnName(),dataSourceBuilder.build());
}
}
return map;
}
@Bean
public DataSource csgDataSource(){
DynamicDataSource dynamicDataSource=new DynamicDataSource();
Map<Object,Object>dataSourceMap=getDataSourceMap();
dynamicDataSource.setTargetDataSources(dataSourceMap);
Object object= dataSourceMap.values().toArray()[0];
dynamicDataSource.setDefaultTargetDataSource(object);
return dynamicDataSource;
}
public void setJdbc(List<DataSourceModel> jdbc) {
this.jdbc = jdbc;
}
public List<DataSourceModel> getJdbc(){
return this.jdbc;
}
}
第四部
@Configuration
public class MyBatisConfig {
@Autowired
private DataSource csgDataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(csgDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/**/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager platformTransactionManager(){
return new DataSourceTransactionManager(csgDataSource);
}
}
第五步
/**
* 注解标签
* 作用于 方法、接口、类、枚举、注解
* */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface TargetDataSource {
String connName();
}
第六步
@Aspect
@Component
public class DataSourceExchange {
@Before("@annotation(TargetDataSource)")
public void before(JoinPoint joinPoint){
MethodSignature sign = (MethodSignature) joinPoint.getSignature();
Method method = sign.getMethod();
boolean isMethodAop= method.isAnnotationPresent(TargetDataSource.class);
if (isMethodAop){
TargetDataSource datasource = method.getAnnotation(TargetDataSource.class);
DataSourceHolder.setDataSources(datasource.connName());
}else {
if (joinPoint.getTarget().getClass().isAnnotationPresent(TargetDataSource.class)){
TargetDataSource datasource = joinPoint.getTarget().getClass().getAnnotation(TargetDataSource.class);
DataSourceHolder.setDataSources(datasource.connName());
}
}
}
@After("@annotation(TargetDataSource)")
public void after(){
DataSourceHolder.clearDataSource();
}
}
第七部
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@TargetDataSource(connName = "nacos")
public List<UserEntity> getList() {
List<UserEntity> list= userMapper.selectUserList();
return list;
}
}
笔者从事java开发工作不多,改方法可能不是太好,也请各位看官勿喷~