test:(修证)

dev
zhang xu 2024-06-08 12:02:28 +08:00
parent ca1760e726
commit aa37b31d18
10 changed files with 252 additions and 468 deletions

View File

@ -1,26 +0,0 @@
package com.muyu;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
import com.muyu.common.security.annotation.EnableCustomConfig;
import com.muyu.common.security.annotation.EnableMyFeignClients;
import com.muyu.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
* @ClassDescription:
* @JdkVersion: 17
* @Author: zhangxu
* @Created: 2024/6/3 21:00
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableMyFeignClients
@SpringBootApplication(exclude = {DynamicDataSourceAutoConfiguration.class
,DataSourceAutoConfiguration.class})
public class CloudManyDataSourceApplication {
public static void main(String[] args) {
SpringApplication.run(CloudManyDataSourceApplication.class);
}
}

View File

@ -1,52 +0,0 @@
package com.muyu.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.config.holder.DynamicDataSourceHolder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.util.Map;
/**
* @ClassDescription:
* @JdkVersion: 17
* @Author: zhangxu
* @Created: 2024/6/4 8:54
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DynamicDataSource extends AbstractRoutingDataSource {
/***
*
*
*
* **/
private Map<Object, Object> defineTargetDataSources;
public void put(String key, DruidDataSource value){
defineTargetDataSources.put(key,value);
}
/**
*
* 线使
* **/
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDynamicDatasourceKey();
}
}

View File

@ -1,34 +0,0 @@
package com.muyu.config.contents;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.remote.RemoteUserService;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
/**
* @ClassDescription:
* @JdkVersion: 17
* @Author: zhangxu
* @Created: 2024/6/6 21:13
*/
public class DataSourceAsp {
@Pointcut("execution(public * com.zhiLian.vehicle.controller.*Controller.*(..))")
public void pointcut() {
}
@Lazy
@Autowired
private RemoteUserService remoteUserService;
@Before("pointcut()")
public void beforeMethod(){
Long userid = SecurityUtils.getLoginUser().getUserid();
remoteUserService.
}
}

View File

@ -1,18 +0,0 @@
package com.muyu.config.contents;
/**
* @ClassDescription:
* @JdkVersion: 17
* @Author: zhangxu
* @Created: 2024/6/4 9:33
*/
public class DatasourceContent {
public final static String PASSWORDS = "sal75-z";
public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/etl?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai";
public final static String DATASOURCE_USERNAME = "root";
}

View File

@ -1,47 +0,0 @@
package com.muyu.config.domain.model;
import com.muyu.common.core.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import static com.muyu.config.contents.DatasourceContent.*;
/**
* @ClassDescription:
* @JdkVersion: 17
* @Author: zhangxu
* @Created: 2024/6/4 9:30
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DataSourceInfo {
private String key;
private String url;
private String userName;
private String password;
public static DataSourceInfo getDataSourceInfo(String key,String host,Integer port)
{
return DataSourceInfo.builder()
.key(key)
.url(StringUtils.format(DATASOURCE_URL,host,port))
.userName(DATASOURCE_USERNAME)
.password(PASSWORDS)
.build();
}
}

View File

@ -1,39 +0,0 @@
package com.muyu.config.factory;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.config.domain.model.DataSourceInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import java.sql.SQLException;
/**
* @ClassDescription:
* @JdkVersion: 17
* @Author: zhangxu
* @Created: 2024/6/4 9:09
*/
@Log4j2
@Component
public class DruidDataSourceFactory {
public DruidDataSource create(DataSourceInfo dataSourceInfo){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(dataSourceInfo.getUrl());
druidDataSource.setUsername(dataSourceInfo.getUserName());
druidDataSource.setPassword(dataSourceInfo.getPassword());
druidDataSource.setBreakAfterAcquireFailure(true);
druidDataSource.setConnectionErrorRetryAttempts(0);
try {
druidDataSource.getConnection(2000);
log.info("连接成功");
return druidDataSource;
} catch (SQLException e) {
log.error("连接失败");
return null;
}
}
}

View File

@ -1,36 +1,36 @@
package com.muyu.networking.controller;
import com.muyu.common.core.domain.Result;
import com.muyu.domain.datasources.SongInfo;
import com.muyu.networking.service.SongService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* songController
*
* @author GuanTieLin
* @date 2024-05-16
*/
@RestController
@RequestMapping("/song")
public class SongController {
@Autowired
private SongService songService; // songService接口
/**
*
*/
@GetMapping("/list")
public Result<List<SongInfo>> list() { // song_info对象
return Result.success(songService.list()); // 查询song列表
}
}
//package com.muyu.networking.controller;
//
//
//import com.muyu.common.core.domain.Result;
//import com.muyu.domain.datasources.SongInfo;
//import com.muyu.networking.service.SongService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import java.util.List;
//
///** 多数据源
// * songController
// *
// * @author 张zhangxu
// * @date 2024-05-16
// */
//@RestController
//@RequestMapping("/song")
//public class SongController {
//
// @Autowired
// private SongService songService; // songService接口
//
// /**
// * 查询歌曲列表
// */
// @GetMapping("/list")
// public Result<List<SongInfo>> list() { // song_info对象
// return Result.success(songService.list()); // 查询song列表
// }
//
//}
//

View File

@ -1,113 +1,113 @@
package com.muyu.vehicle.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* Druid
* @ClassName DruidDBConfig
* @Author
* @Date 2024/4/28 17:16
*/
@Log4j2
@Configuration
public class DruidDBConfig {
@Value("${spring.datasource.dynamic.datasource.slave.url}")
private String dbUrl;
@Value("${spring.datasource.dynamic.datasource.slave.username}")
private String username;
@Value("${spring.datasource.dynamic.datasource.slave.password}")
private String password;
@Value("${spring.datasource.dynamic.datasource.slave.driver-class-name}")
private String driverClassName;
//连接池连接信息
@Value("${spring.datasource.dynamic.druid.initial-size}")
private int initialSize;
@Value("${spring.datasource.dynamic.druid.min-idle}")
private int minIdle;
@Value("${spring.datasource.dynamic.druid.max-active}")
private int maxActive;
@Value("${spring.datasource.dynamic.druid.max-wait}")
private int maxWait;
@Bean
@Primary
@Qualifier("mainDataSource")
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
// 基础连接信息
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
// 连接池连接信息
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
//是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
datasource.setPoolPreparedStatements(false);
datasource.setMaxPoolPreparedStatementPerConnectionSize(20);
//申请连接时执行validationQuery检测连接是否有效这里建议配置为TRUE防止取到的连接不可用
datasource.setTestOnBorrow(true);
//建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
datasource.setTestWhileIdle(true);
//用来检测连接是否有效的sql
datasource.setValidationQuery("select 1 from dual");
//配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
datasource.setTimeBetweenEvictionRunsMillis(60000);
//配置一个连接在池中最小生存的时间单位是毫秒这里配置为3分钟180000
datasource.setMinEvictableIdleTimeMillis(180000);
datasource.setKeepAlive(true);
return datasource;
}
@Bean(name = "dynamicDataSource")
@Qualifier("dynamicDataSource")
public DynamicRoutingDataSource dynamicDataSource() {
DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
dynamicDataSource.setDebug(false);
//配置缺省的数据源
dynamicDataSource.setDefaultTargetDataSource(dataSource());
Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
//额外数据源配置 TargetDataSources
targetDataSources.put("mainDataSource", dataSource());
dynamicDataSource.setTargetDataSources(targetDataSources);
return dynamicDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
//用mybatis的这里会有点区别mybatis用的是SqlSessionFactoryBean
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dynamicDataSource());
//配置resources包下的xml文件扫描路径
//sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
/**
*
* @param dataSource
* @return org.springframework.jdbc.datasource.DataSourceTransactionManager
*/
@Bean
public DataSourceTransactionManager transactionManager(DynamicRoutingDataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
//package com.muyu.vehicle.config;
//import com.alibaba.druid.pool.DruidDataSource;
//
//import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
//import lombok.extern.log4j.Log4j2;
//import org.apache.ibatis.session.SqlSessionFactory;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//import javax.sql.DataSource;
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * Druid数据库连接池配置
// * @ClassName DruidDBConfig
// * @Author
// * @Date 2024/4/28 17:16
// */
//@Log4j2
//@Configuration
//public class DruidDBConfig {
//
// @Value("${spring.datasource.dynamic.datasource.slave.url}")
// private String dbUrl;
// @Value("${spring.datasource.dynamic.datasource.slave.username}")
// private String username;
// @Value("${spring.datasource.dynamic.datasource.slave.password}")
// private String password;
// @Value("${spring.datasource.dynamic.datasource.slave.driver-class-name}")
// private String driverClassName;
// //连接池连接信息
// @Value("${spring.datasource.dynamic.druid.initial-size}")
// private int initialSize;
// @Value("${spring.datasource.dynamic.druid.min-idle}")
// private int minIdle;
// @Value("${spring.datasource.dynamic.druid.max-active}")
// private int maxActive;
// @Value("${spring.datasource.dynamic.druid.max-wait}")
// private int maxWait;
//
// @Bean
// @Primary
// @Qualifier("mainDataSource")
// public DataSource dataSource() {
// DruidDataSource datasource = new DruidDataSource();
// // 基础连接信息
// datasource.setUrl(this.dbUrl);
// datasource.setUsername(username);
// datasource.setPassword(password);
// datasource.setDriverClassName(driverClassName);
// // 连接池连接信息
// datasource.setInitialSize(initialSize);
// datasource.setMinIdle(minIdle);
// datasource.setMaxActive(maxActive);
// datasource.setMaxWait(maxWait);
// //是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
// datasource.setPoolPreparedStatements(false);
// datasource.setMaxPoolPreparedStatementPerConnectionSize(20);
// //申请连接时执行validationQuery检测连接是否有效这里建议配置为TRUE防止取到的连接不可用
// datasource.setTestOnBorrow(true);
// //建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
// datasource.setTestWhileIdle(true);
// //用来检测连接是否有效的sql
// datasource.setValidationQuery("select 1 from dual");
// //配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
// datasource.setTimeBetweenEvictionRunsMillis(60000);
// //配置一个连接在池中最小生存的时间单位是毫秒这里配置为3分钟180000
// datasource.setMinEvictableIdleTimeMillis(180000);
// datasource.setKeepAlive(true);
// return datasource;
// }
//
//
// @Bean(name = "dynamicDataSource")
// @Qualifier("dynamicDataSource")
// public DynamicRoutingDataSource dynamicDataSource() {
// DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
// dynamicDataSource.setDebug(false);
// //配置缺省的数据源
// dynamicDataSource.setDefaultTargetDataSource(dataSource());
// Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
// //额外数据源配置 TargetDataSources
// targetDataSources.put("mainDataSource", dataSource());
// dynamicDataSource.setTargetDataSources(targetDataSources);
// return dynamicDataSource;
// }
//
//
// @Bean
// public SqlSessionFactory sqlSessionFactory() throws Exception {
// //用mybatis的这里会有点区别mybatis用的是SqlSessionFactoryBean
// MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
// sqlSessionFactoryBean.setDataSource(dynamicDataSource());
// //配置resources包下的xml文件扫描路径
// //sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml"));
// return sqlSessionFactoryBean.getObject();
// }
//
// /**
// * 将动态数据加载类添加到事务管理器
// * @param dataSource 数据源
// * @return org.springframework.jdbc.datasource.DataSourceTransactionManager
// */
// @Bean
// public DataSourceTransactionManager transactionManager(DynamicRoutingDataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
//}
//

View File

@ -1,44 +1,44 @@
package com.muyu.vehicle.context;
import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.extern.log4j.Log4j2;
/**
*
* @ClassName DataSourceContextHolder
* @Author
* @Date 2024/4/28 16:47
*/
@Log4j2
public class DataSourceContextHolder {
/**
* 线
*/
private static final TransmittableThreadLocal<Long> CONTEXT_HOLDER = new TransmittableThreadLocal<>();
/**
*
*/
public static void setDataSource(Long datasourceId) {
CONTEXT_HOLDER.set(datasourceId);
log.info("已切换到数据源:{}",datasourceId);
}
/**
*
* @return
*/
public static Long getDataSource() {
return CONTEXT_HOLDER.get();
}
/**
*
*/
public static void removeDataSource() {
CONTEXT_HOLDER.remove();
log.info("已切换到主数据源");
}
}
//package com.muyu.vehicle.context;
//
//import com.alibaba.ttl.TransmittableThreadLocal;
//import lombok.extern.log4j.Log4j2;
//
///**
// * 当前数据源
// * @ClassName DataSourceContextHolder
// * @Author
// * @Date 2024/4/28 16:47
// */
//@Log4j2
//public class DataSourceContextHolder {
//
// /**
// * 线程级别的私有变量
// */
// private static final TransmittableThreadLocal<Long> CONTEXT_HOLDER = new TransmittableThreadLocal<>();
//
// /**
// * 切换数据源
// */
// public static void setDataSource(Long datasourceId) {
// CONTEXT_HOLDER.set(datasourceId);
// log.info("已切换到数据源:{}",datasourceId);
// }
//
// /**
// * 获取当前数据源
// * @return 数据源编号
// */
// public static Long getDataSource() {
// return CONTEXT_HOLDER.get();
// }
//
// /**
// * 删除数据源
// */
// public static void removeDataSource() {
// CONTEXT_HOLDER.remove();
// log.info("已切换到主数据源");
// }
//}
//

View File

@ -1,59 +1,59 @@
package com.muyu.vehicle.service.Impl;
import com.muyu.domain.datasources.Datasource;
import com.muyu.vehicle.config.DynamicRoutingDataSource;
import com.muyu.vehicle.context.DataSourceContextHolder;
import com.muyu.vehicle.mapper.DataSourceMapper;
import com.muyu.vehicle.service.DataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @ClassName
* @Author
* @Date
*/
@Service
public class DataSourceServiceImpl implements DataSourceService {
@Autowired
private DataSourceMapper dataSourceMapper;
@Autowired
private DynamicRoutingDataSource dynamicRoutingDataSource;
@Override
public void toDefaultDS() {
//切到默认数据源
DataSourceContextHolder.removeDataSource(); // 删除数据源
}
@Override
public boolean changeDS(Long datasourceId) {
//切到默认数据源
DataSourceContextHolder.removeDataSource(); // 删除数据源
//找到所有的配置
List<Datasource> dataSourceList = dataSourceMapper.selectList(null); // 数据源对象
if(!dataSourceList.isEmpty()){
for (Datasource dataSource : dataSourceList) { // 数据源对象
if(dataSource.getId().equals(datasourceId)){ // 编号
System.out.println("已找到数据源,datasourceId是" + dataSource.getId()); // 编号
//判断连接是否存在,不存在就创建
dynamicRoutingDataSource.checkCreateDataSource(dataSource); // 检查数据源是否已经创建
//切换数据源
DataSourceContextHolder.setDataSource(dataSource.getId()); // 编号 --> 切换数据源
return true;
}
}
}
return false;
}
}
//package com.muyu.vehicle.service.Impl;
//
//
//
//import com.muyu.domain.datasources.Datasource;
//
//import com.muyu.vehicle.config.DynamicRoutingDataSource;
//import com.muyu.vehicle.context.DataSourceContextHolder;
//import com.muyu.vehicle.mapper.DataSourceMapper;
//import com.muyu.vehicle.service.DataSourceService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//
//import java.util.List;
//
///**
// * @ClassName
// * @Author
// * @Date
// */
//@Service
//public class DataSourceServiceImpl implements DataSourceService {
//
// @Autowired
// private DataSourceMapper dataSourceMapper;
//
// @Autowired
// private DynamicRoutingDataSource dynamicRoutingDataSource;
//
// @Override
// public void toDefaultDS() {
// //切到默认数据源
// DataSourceContextHolder.removeDataSource(); // 删除数据源
// }
//
// @Override
// public boolean changeDS(Long datasourceId) {
// //切到默认数据源
// DataSourceContextHolder.removeDataSource(); // 删除数据源
// //找到所有的配置
// List<Datasource> dataSourceList = dataSourceMapper.selectList(null); // 数据源对象
//
// if(!dataSourceList.isEmpty()){
// for (Datasource dataSource : dataSourceList) { // 数据源对象
// if(dataSource.getId().equals(datasourceId)){ // 编号
// System.out.println("已找到数据源,datasourceId是" + dataSource.getId()); // 编号
// //判断连接是否存在,不存在就创建
// dynamicRoutingDataSource.checkCreateDataSource(dataSource); // 检查数据源是否已经创建
// //切换数据源
// DataSourceContextHolder.setDataSource(dataSource.getId()); // 编号 --> 切换数据源
// return true;
// }
// }
// }
// return false;
// }
//
//}
//