Springboot MyBatisPlus以及Druid配置多数据源
前言:我们在开发项目时,有时不止访问一个数据库,可能会同时连接多个数据库。如果通过写接口的方式进行访问,如果其中一个项目中断,则会影响系统的运行,如果解决这种问题呢?最好的方式就是直接访问数据库,这样不但效率高,而且可以减少大量的开发任务。一、数据库配置文件目录,如图:二、文件内容详情1、DataSourceAspect/*** 使用切面进行数据库切换* @author charlin* @ver
·
前言:
我们在开发项目时,有时不止访问一个数据库,可能会同时连接多个数据库。如果通过写接口的方式进行访问,如果其中一个项目中断,则会影响系统的运行,如果解决这种问题呢?最好的方式就是直接访问数据库,这样不但效率高,而且可以减少大量的开发任务。
一、数据库配置文件目录,如图:
二、文件内容详情
1、DataSourceAspect
/**
* 使用切面进行数据库切换
* @author charlin
* @version 0.01
*/
@Aspect
@Component
@Slf4j
public class DataSourceAspect implements Ordered {
@Pointcut("@annotation(com.wys.mall.dataSource.IDataSource)")//注意:这里的xxxx代表的是上面public @interface DataSource这个注解DataSource的包名
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
IDataSource ds = method.getAnnotation(IDataSource.class);
if (ds == null) {
DynamicDataSource.setDataSource(DataSourceNames.CLOUD);
log.debug("set datasource is " + DataSourceNames.CLOUD);
} else {
DynamicDataSource.setDataSource(ds.name());
log.debug("set datasource is " + ds.name());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
log.debug("clean datasource");
}
}
@Override
public int getOrder() {
return 1;
}
}
2、DataSourceNames
/**
* 数据源名称
* @author charlin
* @version 0.01
* @date 2020-09-20
*/
public interface DataSourceNames {
String CLOUD = "cloud";
String YAODIAN = "yaodian";
}
3、DynamicDataSource
/**
* 设置数据源切换
* @author chalrin
* @version 0.01
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(new HashMap<Object, Object>(targetDataSources));
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
4、数据源配置DynamicDataSourceConfig
/**
* 数据源配置
* @author charlin
* @version 0.01
*/
@Configuration
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.cloud")
public DataSource cloudDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.yaodian")
public DataSource yaodianDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource cloudDataSource, DataSource yaodianDataSource) {
Map<String, DataSource> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceNames.CLOUD, cloudDataSource);
targetDataSources.put(DataSourceNames.YAODIAN, yaodianDataSource);
return new DynamicDataSource(cloudDataSource, targetDataSources);
}
}
5、设置默认的数据源IDataSource
/**
* 设置默认的数据源
* @author charlin
* @version 0.01
*/
@Target(ElementType.METHOD)
//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
@Retention(RetentionPolicy.RUNTIME)
public @interface IDataSource {
String name() default "cloud";
}
6、事务控制器TransactionConfig
/**
* 事务控制器
* @author charlin
* @Title: ${file_name}
* @Package ${package_name}
* @date 2020/9/2920:43
*/
@Configuration
public class TransactionConfig {
public static final String CLOUD_TX = "cloud_tx";
public static final String YAODIAN_TX = "yaodian_tx";
//使用,在方法上添加 @Transactional(value = TransactionConfig.CLOUD_TX, rollbackFor = Exception.class)
@Bean(name = TransactionConfig.CLOUD_TX)
public DataSourceTransactionManager cloudTransactionManager(DataSource cloudDataSource){
return new DataSourceTransactionManager(cloudDataSource);
}
@Bean(name = TransactionConfig.YAODIAN_TX)
public DataSourceTransactionManager yaodianTransactionManager(DataSource yaodianDataSource){
return new DataSourceTransactionManager(yaodianDataSource);
}
}
三、MyBatisPlus配置
/**
* 作用:mybatisPlus配置<br>
* 说明:(无)
*
* @author charlin
* @Date 2019年04月08日 16:47
*/
@Configuration
@MapperScan("com.wys.mall.*.mapper")
@EnableTransactionManagement
@Aspect
public class MybatisPlusConfig {
/**
* 注入sql注入器
*/
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
@Bean
@Profile({"dev","prod","test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
performanceInterceptor.setMaxTime(100000);
/*<!--SQL是否格式化 默认false-->*/
performanceInterceptor.setFormat(false);
return performanceInterceptor;
}
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//文件最大
factory.setMaxFileSize(DataSize.of(202400L, DataUnit.KILOBYTES)); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize(DataSize.of(1024000L, DataUnit.KILOBYTES));
return factory.createMultipartConfig();
}
/**
* 配置分页插件
* @return page
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
/**
* 乐观锁 配置
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
/**
* 新增/编辑时自动填充修改人/添加人/创建时间/修改日期
* 自动填充功能
* @return
*/
@Bean
public GlobalConfig globalConfig() {
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setMetaObjectHandler(new MyMetaObjectHandler());
return globalConfig;
}
}
四、资源文件配置,如图:
1、application.yml
server:
port: 8282
servlet:
session:
timeout: 3600000000s
spring:
# 使用环境
profiles:
active: dev
session:
timeout: 3600000000s
#日期配置
jackson:
date-format: yyyy/MM/dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
# mybatis-plus 配置
mybatis-plus:
check-config-location: false
type-aliases-package: com.wys.mall.*.entity
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
#日志输出
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: UUID
table-underline: true
#驼峰下划线转换
column-underline: true
db-type: mysql
logic-delete-value: 1 #默认值1
logic-not-delete-value: 0 #默认值0
#刷新mapper
refresh-mapper: true
#日志
logging:
config: classpath:logback-spring.xml
log:
file: D:/log
#swagger api记录
swagger:
show: true
2、application-dev.yml
spring:
# druid数据源配置
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
cloud:
url: jdbc:mysql://192.168.16.100:9090/member?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: sa
password: sa
yaodian:
url: jdbc:mysql://192.168.16.100:9090/yaodian?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: sa
password: sa
filters: stat,wall,config
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
web-stat-filter:
# 添加过滤规则
url-pattern: /*
# 忽略过滤格式
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
stat-view-servlet:
# 是否可以重置数据
reset-enable: false
# 开启druid监控页面
enabled: true
# 静态资料访问方式
mvc:
static-path-pattern: /static/**
# thymeleaf 模块配置
thymeleaf:
prefix: classpath:/templates/
suffix: .html
mode: LEGACYHTML5
encoding: utf-8
# 关闭页面缓存
cache: false
servlet:
content-type: text/html
# redis配置
redis:
# Redis数据库索引
database: 0
# Redis服务器地址
host: localhost
port: 6379
password:
jedis:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
# max-wait: -1
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
# 连接超时时间(毫秒)
timeout: 10000s
session:
store-type: redis
# cloud自定义配置
cloud:
# 登录验证码是否开启,开发环境配置false方便测试
login:
authcode:
enable: false
# quartz开关
quartz:
enable: true
# 缓存开关
cache:
enable: false
五、项目中使用
@Override
@IDataSource(name = DataSourceNames.CLOUD)
@Transactional(value = TransactionConfig.CLOUD_TX, rollbackFor = Exception.class)
public Integer update() {
..............................
}
六、启动
@Slf4j
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 360000)
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
@EnableScheduling
@EnableTransactionManagement(proxyTargetClass = true)
public class MyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
}

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)