first commit
This commit is contained in:
@ -1,40 +1,27 @@
|
||||
qiaoba:
|
||||
file-upload-path: C:/${spring.application.name}/uploadPath/
|
||||
datasource:
|
||||
master:
|
||||
driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/${spring.application.name}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
dataSources:
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://192.168.0.202:3306/${spring.application.name}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: root
|
||||
pool:
|
||||
init: 5 #连接池初始化大小
|
||||
min: 10 #最小空闲连接数
|
||||
max: 20 #最大连接数
|
||||
slaves:
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://121.5.136.69:3306/qiaoba-boot-1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: LpYN7LUoL?l0OSpR2
|
||||
pool:
|
||||
init: 5
|
||||
min: 10
|
||||
max: 20
|
||||
weight: 2 #权重 默认 1
|
||||
is-use: true #是否使用 默认 true
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/qiaoba-boot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: root
|
||||
pool:
|
||||
init: 5
|
||||
min: 10
|
||||
max: 20
|
||||
is-use: false # 不使用该库
|
||||
password: Root123456789.
|
||||
#连接池初始化大小
|
||||
initial-size: 5
|
||||
#最小空闲线程数
|
||||
min-idle: 10
|
||||
#最大连接池数量
|
||||
max-active: 20
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://192.168.0.203:3306/${spring.application.name}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: Root123456789.
|
||||
#连接池初始化大小
|
||||
initial-size: 5
|
||||
#最小空闲线程数
|
||||
min-idle: 10
|
||||
#最大连接池数量
|
||||
max-active: 20
|
||||
|
||||
# 连接测试query(配置检测连接是否有效)
|
||||
connectionTestQuery: SELECT 1
|
||||
# 多久检查一次连接的活性
|
||||
keepaliveTime: 30000
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
|
@ -1,35 +1,26 @@
|
||||
qiaoba:
|
||||
file-upload-path: /opt/${spring.application.name}/uploadPath/
|
||||
datasource:
|
||||
master:
|
||||
driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/qiaoba-boot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
dataSources:
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://192.168.0.202:3306/${spring.application.name}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: root
|
||||
pool:
|
||||
init: 5 #连接池初始化大小
|
||||
min: 10 #最小空闲连接数
|
||||
max: 20 #最大连接数
|
||||
slaves:
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://121.5.136.69:3306/qiaoba-boot-1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: LpYN7LUoL?l0OSpR2
|
||||
pool:
|
||||
init: 5
|
||||
min: 10
|
||||
max: 20
|
||||
weight: 2 #权重 默认 1
|
||||
is-use: true #是否使用 默认 true
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/qiaoba-boot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: root
|
||||
pool:
|
||||
init: 5
|
||||
min: 10
|
||||
max: 20
|
||||
is-use: false # 不使用该库
|
||||
password: Root123456789.
|
||||
#连接池初始化大小
|
||||
initial-size: 5
|
||||
#最小空闲线程数
|
||||
min-idle: 10
|
||||
#最大连接池数量
|
||||
max-active: 20
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://192.168.0.203:3306/${spring.application.name}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: Root123456789.
|
||||
#连接池初始化大小
|
||||
initial-size: 5
|
||||
#最小空闲线程数
|
||||
min-idle: 10
|
||||
#最大连接池数量
|
||||
max-active: 20
|
||||
|
||||
|
||||
mybatis-plus:
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.qiaoba.common.database.config;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.qiaoba.common.base.constants.TenantConstant;
|
||||
@ -8,12 +7,8 @@ import com.qiaoba.common.base.context.BaseContext;
|
||||
import com.qiaoba.common.base.enums.BaseEnum;
|
||||
import com.qiaoba.common.database.constants.DynamicDatasourceConstant;
|
||||
import com.qiaoba.common.database.entity.DynamicDataSource;
|
||||
import com.qiaoba.common.database.properties.DefaultDataSourceProperties;
|
||||
import com.qiaoba.common.database.properties.MasterInfo;
|
||||
import com.qiaoba.common.database.properties.PoolInfo;
|
||||
import com.qiaoba.common.database.properties.SlaveInfo;
|
||||
import com.qiaoba.common.database.properties.DataSourceProperties;
|
||||
import com.qiaoba.common.database.service.DynamicDatasourceService;
|
||||
import com.qiaoba.common.database.utils.JdbcUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@ -21,7 +16,10 @@ import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -41,19 +39,19 @@ public class DynamicDataSourceConfig {
|
||||
@Resource
|
||||
private DynamicDataSourceContext dataSource;
|
||||
@Resource
|
||||
private DefaultDataSourceProperties defaultDataSourceProperties;
|
||||
private DataSourceProperties dataSourceProperties;
|
||||
@Resource
|
||||
private DynamicDatasourceService dynamicDatasourceService;
|
||||
|
||||
/**
|
||||
* 使用中的数据源
|
||||
* 主要数据源
|
||||
*/
|
||||
public static Map<Object, Object> MASTER_SOURCE_MAP = new ConcurrentHashMap<>();
|
||||
public static Map<Object, Object> PRIMARY_DATASOURCE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 备用数据源
|
||||
* 备用数据源-每次取0索引
|
||||
*/
|
||||
public static Map<String, List<SlaveInfo>> SLAVE_SOURCE_MAP = new ConcurrentHashMap<>();
|
||||
public static Map<String, List<DynamicDataSource>> BACKUP_DATASOURCE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 把DynamicDataSourceContext 纳入容器管理,其他地方使用DynamicDataSourceConfig 类可以直接从容器取对象,并调用freshDataSource方法
|
||||
@ -67,72 +65,51 @@ public class DynamicDataSourceConfig {
|
||||
}
|
||||
|
||||
private void initDefault() {
|
||||
MasterInfo master = defaultDataSourceProperties.getMaster();
|
||||
List<SlaveInfo> slaves = defaultDataSourceProperties.getSlaves();
|
||||
// 将主数据源使用
|
||||
addMasterMap(DynamicDatasourceConstant.MASTER_PREFIX + TenantConstant.DEFAULT_TENANT_ID, buildDataSource(master.getDriver(), master.getUrl(), master.getUsername(), master.getPassword(), master.getPool()));
|
||||
dataSource.freshDataSource(MASTER_SOURCE_MAP);
|
||||
// 将从数据源备用
|
||||
if (CollUtil.isNotEmpty(slaves)) {
|
||||
for (int i = 0; i < slaves.size(); i++) {
|
||||
if (!slaves.get(i).getIsUse()) {
|
||||
slaves.remove(i);
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(slaves)) {
|
||||
SLAVE_SOURCE_MAP.put(DynamicDatasourceConstant.SLAVE_PREFIX + TenantConstant.DEFAULT_TENANT_ID, slaves);
|
||||
}
|
||||
}
|
||||
List<DynamicDataSource> dataSources = dataSourceProperties.getDataSources();
|
||||
// 0索引作为主数据源
|
||||
addPrimaryMap(DynamicDatasourceConstant.MASTER_PREFIX + TenantConstant.DEFAULT_TENANT_ID, buildDataSource(dataSources.get(0)));
|
||||
dataSources.remove(0);
|
||||
// 非0索引的备用
|
||||
addBackupMap(TenantConstant.DEFAULT_TENANT_ID, dataSources);
|
||||
// 刷新数据源
|
||||
dataSource.freshDataSource(PRIMARY_DATASOURCE_MAP);
|
||||
}
|
||||
|
||||
private void initTenant() {
|
||||
setDefaultSetting();
|
||||
List<DynamicDataSource> dynamicDataSourceList = dynamicDatasourceService.loadAllTenantDatasource();
|
||||
for (DynamicDataSource dynamicDataSource : dynamicDataSourceList) {
|
||||
// 将主数据源加载
|
||||
if (BaseEnum.YES.getCode().equals(dynamicDataSource.getIsMaster())) {
|
||||
addMasterMap(DynamicDatasourceConstant.MASTER_PREFIX + dynamicDataSource.getTenantId(), buildDataSource(dynamicDataSource.getDriver(), dynamicDataSource.getUrl(), dynamicDataSource.getUsername(), dynamicDataSource.getPassword(), new PoolInfo(dynamicDataSource.getInitCount(), dynamicDataSource.getMinCount(), dynamicDataSource.getMaxCount())));
|
||||
dataSource.freshDataSource(MASTER_SOURCE_MAP);
|
||||
}
|
||||
// 将从数据源备用
|
||||
else {
|
||||
if (Objects.isNull(SLAVE_SOURCE_MAP.get(DynamicDatasourceConstant.MASTER_PREFIX + dynamicDataSource.getTenantId()))) {
|
||||
List<SlaveInfo> slaves = new ArrayList<>();
|
||||
slaves.add(datasourceToSlave(dynamicDataSource));
|
||||
SLAVE_SOURCE_MAP.put(DynamicDatasourceConstant.MASTER_PREFIX + dynamicDataSource.getTenantId(), slaves);
|
||||
} else {
|
||||
List<SlaveInfo> slaves = SLAVE_SOURCE_MAP.get(DynamicDatasourceConstant.MASTER_PREFIX + dynamicDataSource.getTenantId());
|
||||
slaves.add(datasourceToSlave(dynamicDataSource));
|
||||
Map<String, List<DynamicDataSource>> tenantDatasource = dynamicDatasourceService.loadAllTenantDatasource();
|
||||
for (String tenantId : tenantDatasource.keySet()) {
|
||||
List<DynamicDataSource> dataSources = tenantDatasource.get(tenantId);
|
||||
for (int i = 0; i < dataSources.size(); i++) {
|
||||
DynamicDataSource dynamicDataSource = dataSources.get(i);
|
||||
if (BaseEnum.YES.getCode().equals(dynamicDataSource.getIsPrimary())) {
|
||||
addPrimaryMap(DynamicDatasourceConstant.MASTER_PREFIX + tenantId, buildDataSource(dataSources.get(i)));
|
||||
// 去除主要数据源,剩下皆为备用数据源
|
||||
dataSources.remove(i);
|
||||
}
|
||||
}
|
||||
// 备用数据源
|
||||
addBackupMap(tenantId, dataSources);
|
||||
}
|
||||
BaseContext.clearAllHolder();
|
||||
}
|
||||
|
||||
public void addTenantDataSource(String tenantId, String driver, String url, String username, String password, PoolInfo poolInfo) {
|
||||
addMasterMap(DynamicDatasourceConstant.MASTER_PREFIX + tenantId, buildDataSource(driver, url, username, password, poolInfo));
|
||||
dataSource.freshDataSource(MASTER_SOURCE_MAP);
|
||||
// 刷新数据源
|
||||
dataSource.freshDataSource(PRIMARY_DATASOURCE_MAP);
|
||||
}
|
||||
|
||||
public void deleteTenantDataSource(String tenantId) {
|
||||
MASTER_SOURCE_MAP.remove(DynamicDatasourceConstant.MASTER_PREFIX + tenantId);
|
||||
dataSource.freshDataSource(MASTER_SOURCE_MAP);
|
||||
PRIMARY_DATASOURCE_MAP.remove(DynamicDatasourceConstant.MASTER_PREFIX + tenantId);
|
||||
dataSource.freshDataSource(PRIMARY_DATASOURCE_MAP);
|
||||
}
|
||||
|
||||
private static Object buildDataSource(String driver, String url, String username, String password, PoolInfo poolInfo) {
|
||||
boolean flag = JdbcUtil.checkConnect(driver, url, username, password);
|
||||
if (!flag) {
|
||||
log.error("数据源: " + url + " , 连接失败,请检查!");
|
||||
return null;
|
||||
}
|
||||
private static Object buildDataSource(DynamicDataSource dynamicDataSource) {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setUrl(url);
|
||||
dataSource.setUsername(username);
|
||||
dataSource.setPassword(password);
|
||||
dataSource.setDriverClassName(driver);
|
||||
dataSource.setInitialSize(poolInfo.getInit());
|
||||
dataSource.setMinIdle(poolInfo.getMin());
|
||||
dataSource.setMaxActive(poolInfo.getMax());
|
||||
dataSource.setUrl(dynamicDataSource.getUrl());
|
||||
dataSource.setUsername(dynamicDataSource.getUsername());
|
||||
dataSource.setPassword(dynamicDataSource.getPassword());
|
||||
dataSource.setDriverClassName(dynamicDataSource.getDriver());
|
||||
dataSource.setInitialSize(dynamicDataSource.getInitialSize());
|
||||
dataSource.setMinIdle(dynamicDataSource.getMinIdle());
|
||||
dataSource.setMaxActive(dynamicDataSource.getMaxActive());
|
||||
try {
|
||||
dataSource.init();
|
||||
return dataSource;
|
||||
@ -147,23 +124,28 @@ public class DynamicDataSourceConfig {
|
||||
*/
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
Set<Map.Entry<Object, Object>> entries = MASTER_SOURCE_MAP.entrySet();
|
||||
Set<Map.Entry<Object, Object>> entries = PRIMARY_DATASOURCE_MAP.entrySet();
|
||||
for (Map.Entry<Object, Object> entry : entries) {
|
||||
DruidDataSource dataSource = (DruidDataSource) entry.getValue();
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void addMasterMap(String name, Object dataSource) {
|
||||
private void addPrimaryMap(String name, Object dataSource) {
|
||||
if (Objects.nonNull(dataSource)) {
|
||||
MASTER_SOURCE_MAP.put(name, dataSource);
|
||||
PRIMARY_DATASOURCE_MAP.put(name, dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
private SlaveInfo datasourceToSlave(DynamicDataSource dynamicDataSource) {
|
||||
SlaveInfo slaveInfo = BeanUtil.copyProperties(dynamicDataSource, SlaveInfo.class);
|
||||
slaveInfo.setPool(new PoolInfo(dynamicDataSource.getInitCount(), dynamicDataSource.getMinCount(), dynamicDataSource.getMaxCount()));
|
||||
return slaveInfo;
|
||||
private void addBackupMap(String tenantId, List<DynamicDataSource> dataSources) {
|
||||
if (CollUtil.isNotEmpty(dataSources)) {
|
||||
BACKUP_DATASOURCE_MAP.put(tenantId, dataSources);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDataSources(String tenantId, List<DynamicDataSource> dataSources) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setDefaultSetting() {
|
||||
|
@ -10,7 +10,7 @@ import lombok.NoArgsConstructor;
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @date 2023-04-24 21:47:48
|
||||
* @since 2023-06-13 20:24:31
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@ -24,9 +24,9 @@ public class DynamicDataSource {
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 主库
|
||||
* 主要数据源
|
||||
*/
|
||||
private String isMaster;
|
||||
private String isPrimary;
|
||||
|
||||
/**
|
||||
* 数据库-url
|
||||
@ -51,16 +51,16 @@ public class DynamicDataSource {
|
||||
/**
|
||||
* 连接池-初始化大小
|
||||
*/
|
||||
private Integer initCount;
|
||||
private Integer initialSize;
|
||||
|
||||
/**
|
||||
* 连接池-最小空闲数
|
||||
* 连接池-最小空闲线程数
|
||||
*/
|
||||
private Integer minCount;
|
||||
private Integer minIdle;
|
||||
|
||||
/**
|
||||
* 连接池-最大连接数
|
||||
* 连接池-最大连接池数量
|
||||
*/
|
||||
private Integer maxCount;
|
||||
private Integer maxActive;
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package com.qiaoba.common.database.factories;
|
||||
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceContext;
|
||||
import com.qiaoba.common.database.properties.DefaultDataSourceProperties;
|
||||
import com.qiaoba.common.database.properties.DataSourceProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@ -27,8 +27,8 @@ public class DynamicDataSourceFactory {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultDataSourceProperties defaultDataSourceProperties() {
|
||||
return new DefaultDataSourceProperties();
|
||||
public DataSourceProperties defaultDataSourceProperties() {
|
||||
return new DataSourceProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.qiaoba.common.database.properties;
|
||||
|
||||
import com.qiaoba.common.database.entity.DynamicDataSource;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@ -9,12 +10,11 @@ import java.util.List;
|
||||
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "qiaoba.datasource")
|
||||
@ConfigurationProperties(prefix = "qiaoba")
|
||||
@Data
|
||||
@EnableConfigurationProperties
|
||||
public class DefaultDataSourceProperties {
|
||||
public class DataSourceProperties {
|
||||
|
||||
private MasterInfo master;
|
||||
private List<DynamicDataSource> dataSources;
|
||||
|
||||
private List<SlaveInfo> slaves;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.qiaoba.common.database.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据源-主库-信息
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023-04-23 15:37:43
|
||||
*/
|
||||
@Data
|
||||
public class MasterInfo {
|
||||
private String driver;
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
private PoolInfo pool;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package com.qiaoba.common.database.properties;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 数据源连接池信息
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023-04-23 15:37:43
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PoolInfo {
|
||||
|
||||
/**
|
||||
* 初始连接数
|
||||
*/
|
||||
private Integer init;
|
||||
|
||||
/**
|
||||
* 最小空闲数
|
||||
*/
|
||||
private Integer min;
|
||||
|
||||
/**
|
||||
* 最大连接数
|
||||
*/
|
||||
private Integer max;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.qiaoba.common.database.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据源-从库-信息
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023-04-23 15:37:43
|
||||
*/
|
||||
@Data
|
||||
public class SlaveInfo {
|
||||
private Boolean isUse = true;
|
||||
private String driver;
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 权重
|
||||
*/
|
||||
private Integer weight = 1;
|
||||
private PoolInfo pool;
|
||||
}
|
@ -3,6 +3,7 @@ package com.qiaoba.common.database.service;
|
||||
import com.qiaoba.common.database.entity.DynamicDataSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 动态数据源接口
|
||||
@ -16,7 +17,7 @@ public interface DynamicDatasourceService {
|
||||
/**
|
||||
* 加载所有租户的数据源
|
||||
*
|
||||
* @return 数据源集合
|
||||
* @return 数据源集合 key: tenantId | value: list
|
||||
*/
|
||||
List<DynamicDataSource> loadAllTenantDatasource();
|
||||
Map<String, List<DynamicDataSource>> loadAllTenantDatasource();
|
||||
}
|
||||
|
@ -1,107 +1,45 @@
|
||||
{
|
||||
"groups": [
|
||||
{
|
||||
"name": "qiaoba.datasource",
|
||||
"type": "com.qiaoba.common.database.properties.DefaultDataSourceProperties",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"properties": [
|
||||
{
|
||||
"name": "qiaoba.datasource.master",
|
||||
"type": "com.qiaoba.common.database.properties.MasterInfo",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"name": "qiaoba.dataSources",
|
||||
"type": "java.util.List<com.qiaoba.common.database.entity.DynamicDataSource>",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.driver",
|
||||
"name": "qiaoba.datasources.driver",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.url",
|
||||
"name": "qiaoba.datasources.url",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.username",
|
||||
"name": "qiaoba.datasources.username",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.password",
|
||||
"name": "qiaoba.datasources.password",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.pool",
|
||||
"type": "com.qiaoba.common.database.properties.PoolInfo",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.pool.init",
|
||||
"name": "qiaoba.datasources.initial-size",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.pool.min",
|
||||
"name": "qiaoba.datasources.min-idle",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.master.pool.max",
|
||||
"name": "qiaoba.datasources.max-active",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves",
|
||||
"type": "java.util.List<com.qiaoba.common.database.properties.SlaveInfo>",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.url",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.username",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.password",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.weight",
|
||||
"type": "java.lang.String",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.is-use",
|
||||
"type": "java.lang.Boolean",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.pool",
|
||||
"type": "com.qiaoba.common.database.properties.PoolInfo",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.pool.init",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.pool.min",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
},
|
||||
{
|
||||
"name": "qiaoba.datasource.slaves.pool.max",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "com.qiaoba.common.database.properties.DefaultDataSourceProperties"
|
||||
"sourceType": "com.qiaoba.common.database.properties.DataSourceProperties"
|
||||
}
|
||||
],
|
||||
"hints": []
|
||||
|
@ -59,11 +59,7 @@ public class SysTenantDatasource extends BaseEntity {
|
||||
|
||||
private Integer maxCount;
|
||||
|
||||
private Integer weight;
|
||||
|
||||
private String isMaster = "1";
|
||||
|
||||
private String isUse;
|
||||
private String isPrimary;
|
||||
|
||||
@NotBlank(message = "租户ID", groups = {AddGroup.class, EditGroup.class})
|
||||
@Schema(description = "租户ID")
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.qiaoba.module.tenant.entity.param;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
@ -16,21 +17,15 @@ import java.io.Serializable;
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysTenantDatasourceParam implements Serializable {
|
||||
|
||||
private String tenantId;
|
||||
|
||||
private String isMaster;
|
||||
|
||||
private String isUse;
|
||||
|
||||
private String isPrimary;
|
||||
|
||||
public SysTenantDatasourceParam(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
public SysTenantDatasourceParam(String tenantId, String isMaster) {
|
||||
this.tenantId = tenantId;
|
||||
this.isMaster = isMaster;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package com.qiaoba.module.tenant.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qiaoba.module.tenant.entity.SysTenantDatasource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 租户数据源 数据层
|
||||
*
|
||||
@ -11,4 +13,12 @@ import com.qiaoba.module.tenant.entity.SysTenantDatasource;
|
||||
* @since 2023/6/7 14:47
|
||||
*/
|
||||
public interface SysTenantDatasourceMapper extends BaseMapper<SysTenantDatasource> {
|
||||
|
||||
/**
|
||||
* 查询所有数据源模式的租户ID
|
||||
*
|
||||
* @return tenantIds
|
||||
*/
|
||||
List<String> selectTenantIds();
|
||||
|
||||
}
|
||||
|
@ -15,12 +15,12 @@ import java.util.List;
|
||||
public interface SysTenantDatasourceService {
|
||||
|
||||
/**
|
||||
* 查询租户的主库
|
||||
* 查询租户的主要数据源
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
* @return 数据源
|
||||
*/
|
||||
SysTenantDatasource selectMaster(String tenantId);
|
||||
SysTenantDatasource selectPrimary(String tenantId);
|
||||
|
||||
/**
|
||||
* 新增
|
||||
@ -61,4 +61,11 @@ public interface SysTenantDatasourceService {
|
||||
* @return list
|
||||
*/
|
||||
List<SysTenantDatasource> selectList(SysTenantDatasourceParam param);
|
||||
|
||||
/**
|
||||
* 查询所有数据源模式的租户ID
|
||||
*
|
||||
* @return tenantIds
|
||||
*/
|
||||
List<String> selectTenantIds();
|
||||
}
|
||||
|
@ -12,7 +12,9 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 动态数据源接口
|
||||
@ -28,11 +30,14 @@ public class DynamicDatasourceServiceImpl implements DynamicDatasourceService {
|
||||
private final SysTenantDatasourceService sysTenantDatasourceService;
|
||||
|
||||
@Override
|
||||
public List<DynamicDataSource> loadAllTenantDatasource() {
|
||||
SysTenantDatasourceParam param = new SysTenantDatasourceParam();
|
||||
param.setIsUse(BaseEnum.YES.getCode());
|
||||
List<SysTenantDatasource> datasourceList = sysTenantDatasourceService.selectList(param);
|
||||
return transform(datasourceList);
|
||||
public Map<String, List<DynamicDataSource>> loadAllTenantDatasource() {
|
||||
Map<String, List<DynamicDataSource>> datasourceMap = new LinkedHashMap<>();
|
||||
List<String> tenantIds = sysTenantDatasourceService.selectTenantIds();
|
||||
for (String tenantId : tenantIds) {
|
||||
List<SysTenantDatasource> datasourceList = sysTenantDatasourceService.selectList(new SysTenantDatasourceParam(tenantId));
|
||||
datasourceMap.put(tenantId, transform(datasourceList));
|
||||
}
|
||||
return datasourceMap;
|
||||
}
|
||||
|
||||
private List<DynamicDataSource> transform(List<SysTenantDatasource> datasourceList) {
|
||||
|
@ -26,7 +26,7 @@ public class SysTenantDatasourceServiceImpl implements SysTenantDatasourceServic
|
||||
private final SysTenantDatasourceMapper sysTenantDatasourceMapper;
|
||||
|
||||
@Override
|
||||
public SysTenantDatasource selectMaster(String tenantId) {
|
||||
public SysTenantDatasource selectPrimary(String tenantId) {
|
||||
return sysTenantDatasourceMapper.selectOne(paramToWrapper(new SysTenantDatasourceParam(tenantId, BaseEnum.YES.getCode())));
|
||||
}
|
||||
|
||||
@ -55,13 +55,16 @@ public class SysTenantDatasourceServiceImpl implements SysTenantDatasourceServic
|
||||
return sysTenantDatasourceMapper.selectList(paramToWrapper(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectTenantIds() {
|
||||
return sysTenantDatasourceMapper.selectTenantIds();
|
||||
}
|
||||
|
||||
private QueryWrapper<SysTenantDatasource> paramToWrapper(SysTenantDatasourceParam param) {
|
||||
QueryWrapper<SysTenantDatasource> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda()
|
||||
.eq(StrUtil.isNotBlank(param.getTenantId()), SysTenantDatasource::getTenantId, param.getTenantId())
|
||||
.eq(StrUtil.isNotBlank(param.getIsUse()), SysTenantDatasource::getIsUse, param.getIsUse())
|
||||
.eq(StrUtil.isNotBlank(param.getIsMaster()), SysTenantDatasource::getIsMaster, param.getIsMaster());
|
||||
|
||||
.eq(StrUtil.isNotBlank(param.getIsPrimary()), SysTenantDatasource::getIsPrimary, param.getIsPrimary());
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
@ -12,13 +12,11 @@ import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
|
||||
import com.qiaoba.common.database.entity.PageQuery;
|
||||
import com.qiaoba.common.database.entity.TableDataInfo;
|
||||
import com.qiaoba.common.database.properties.PoolInfo;
|
||||
import com.qiaoba.common.database.utils.JdbcUtil;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import com.qiaoba.module.tenant.entity.SysTenant;
|
||||
import com.qiaoba.module.tenant.entity.SysTenantDatasource;
|
||||
import com.qiaoba.module.tenant.entity.param.SysTenantParam;
|
||||
import com.qiaoba.module.tenant.entity.vo.TenantSettingVo;
|
||||
import com.qiaoba.module.tenant.handler.DataHandlerFactory;
|
||||
import com.qiaoba.module.tenant.mapper.SysTenantMapper;
|
||||
import com.qiaoba.module.tenant.service.SysTenantDatasourceService;
|
||||
@ -121,16 +119,6 @@ public class SysTenantServiceImpl implements SysTenantService {
|
||||
if (!result) {
|
||||
throw new ServiceException("同步数据出错, 数据已回滚");
|
||||
}
|
||||
// 将数据源添加到数据源池中
|
||||
if (sysTenant.getMode().equals(SysTenant.DATASOURCE_MODE)) {
|
||||
SysTenantDatasource master = sysTenantDatasourceService.selectMaster(tenantId);
|
||||
dynamicDataSourceConfig.addTenantDataSource(tenantId,
|
||||
DataBaseEnum.getDriver(master.getType()),
|
||||
DataBaseEnum.getUrl(master.getType(), master.getIp(), master.getPort(), master.getName()),
|
||||
master.getUsername(),
|
||||
master.getPassword(),
|
||||
new PoolInfo(master.getInitCount(), master.getMinCount(), master.getMaxCount()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -204,7 +192,7 @@ public class SysTenantServiceImpl implements SysTenantService {
|
||||
* 处理数据源模式
|
||||
*/
|
||||
private Connection datasource(String tenantId) {
|
||||
SysTenantDatasource master = sysTenantDatasourceService.selectMaster(tenantId);
|
||||
SysTenantDatasource master = sysTenantDatasourceService.selectPrimary(tenantId);
|
||||
if (Objects.isNull(master)) {
|
||||
throw new ServiceException("未找到租户主数据源信息");
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.qiaoba.module.tenant.mapper.SysTenantDatasourceMapper">
|
||||
<select id="selectTenantIds" resultType="string">
|
||||
SELECT `tenant_id` FROM `sys_tenant_datasource` GROUP BY `tenant_id`
|
||||
</select>
|
||||
</mapper>
|
Reference in New Issue
Block a user