由于服務沒有做微服務部署,需要在后臺管理系統(tǒng)訪問其他服務的庫,所以需要用到動態(tài)數(shù)據(jù)源切換
引入依賴
mybatis-plus動態(tài)數(shù)據(jù)源依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
更改配置
spring:
application:
name: appName
datasource:
dynamic:
# 指定默認數(shù)據(jù)源
primary: aaaa1
strict: false
datasource:
# 配置第一個數(shù)據(jù)源
aaaa1:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://host:3306/xxx?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: username
password: password
# 配置第二個數(shù)據(jù)源
aaaa2:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://host:3306/xxx?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: username
password: password
druid:
# 初始連接數(shù)
initialSize: 5
# 最小連接池數(shù)量
minIdle: 10
# 最大連接池數(shù)量
maxActive: 20
# 配置獲取連接等待超時的時間
maxWait: 60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一個連接在池中最小生存的時間,單位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一個連接在池中最大生存的時間,單位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置檢測連接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 設置白名單,不填則允許所有訪問
allow:
url-pattern: /druid/*
# 控制臺管理用戶名和密碼
# login-username: login-username
# login-password: login-password
filter:
stat:
enabled: true
# 慢SQL記錄
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
配置類
package com.ruoyi.framework.config;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.ruoyi.common.utils.StringUtils;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* Mybatis支持*匹配掃描包
*
* @author ruoyi
*/
@Configuration
public class MyBatisConfig {
@Autowired
private Environment env;
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
public static String setTypeAliasesPackage(String typeAliasesPackage) {
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
List<String> allResult = new ArrayList<String>();
try {
for (String aliasesPackage : typeAliasesPackage.split(",")) {
List<String> result = new ArrayList<String>();
aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
Resource[] resources = resolver.getResources(aliasesPackage);
if (resources != null && resources.length > 0) {
MetadataReader metadataReader = null;
for (Resource resource : resources) {
if (resource.isReadable()) {
metadataReader = metadataReaderFactory.getMetadataReader(resource);
try {
result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
if (result.size() > 0) {
HashSet<String> hashResult = new HashSet<String>(result);
allResult.addAll(hashResult);
}
}
if (allResult.size() > 0) {
typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
} else {
throw new RuntimeException("mybatis typeAliasesPackage 路徑掃描錯誤,參數(shù)typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
}
} catch (IOException e) {
e.printStackTrace();
}
return typeAliasesPackage;
}
public Resource[] resolveMapperLocations(String[] mapperLocations) {
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
List<Resource> resources = new ArrayList<Resource>();
if (mapperLocations != null) {
for (String mapperLocation : mapperLocations) {
try {
Resource[] mappers = resourceResolver.getResources(mapperLocation);
resources.addAll(Arrays.asList(mappers));
} catch (IOException e) {
// ignore
}
}
}
return resources.toArray(new Resource[resources.size()]);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis.mapperLocations");
String configLocation = env.getProperty("mybatis.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
// 注意這里使用的是MybatisSqlSessionFactoryBean而不是SqlSessionFactoryBean
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
sessionFactory.setPlugins(new MybatisSqlLoggerInterceptor());
return sessionFactory.getObject();
}
}
添加注解
@DS注解我一般放在dao層,因為覺得這樣更合理
啟動測試
問題:
動態(tài)數(shù)據(jù)源切換時效
當服務層接口添加事務注解,動態(tài)數(shù)據(jù)源切換就會失效,并且會使用默認的主數(shù)據(jù)源
批量處理接口異常
當dao層具體實現(xiàn)繼承了BaseMapper并且服務處使用IService去實現(xiàn),在批量處理時候就會出現(xiàn)異常,此時可以通過更改配置解決
使用 MybatisSqlSessionFactoryBean 替換?SqlSessionFactoryBean
參開原文:mybatis-plus框架TABLE_INFO_CACHE獲取不到對應的TableInfo對象_error: can not execute. because can not find cache-CSDN博客
?
?另一種方式實現(xiàn)(未測試):https://www.cnblogs.com/zhaww/p/12706941.html文章來源:http://www.zghlxwxcb.cn/news/detail-848984.html
根據(jù)Mybatis-plus配置動態(tài)數(shù)據(jù)源-從數(shù)據(jù)庫獲取源_mybatis plus 攔截器怎么獲取當前數(shù)據(jù)庫類型-CSDN博客?文章來源地址http://www.zghlxwxcb.cn/news/detail-848984.html
到了這里,關于Mybatis-plus動態(tài)數(shù)據(jù)源的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!