feat(完善多数据源)
commit
dfe5a2eb41
|
@ -7,7 +7,6 @@ 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;
|
||||
import org.springframework.boot.web.servlet.DynamicRegistrationBean;
|
||||
|
||||
/**
|
||||
* 多数据源启动类
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package com.muyu.many.config;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.muyu.common.core.utils.SpringUtils;
|
||||
import com.muyu.many.config.domai.model.DataSourceInfo;
|
||||
import com.muyu.many.config.domai.model.EntInfo;
|
||||
import com.muyu.many.config.factory.DruidDataSourceFactory;
|
||||
import com.muyu.many.config.role.DynamicDataSource;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 多数据源
|
||||
*
|
||||
* @ClassName ManyDataSource
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 14:10
|
||||
*/
|
||||
|
||||
@Log4j2
|
||||
@Component
|
||||
public class ManyDataSource {
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
new Thread(() ->{
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException ignored) {}
|
||||
DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class);
|
||||
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);;
|
||||
EntInfo entInfo = EntInfo.builder()
|
||||
.entCode("ent_4588")
|
||||
.ip("123.56.102.11")
|
||||
.port(3308)
|
||||
.build();
|
||||
DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(entInfo.getEntCode(), entInfo.getIp(), entInfo.getPort());
|
||||
DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo);
|
||||
dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource);
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
private List<EntInfo> dataSourceInfoList() {
|
||||
List<EntInfo> list = new ArrayList<>();
|
||||
list.add(
|
||||
EntInfo.builder()
|
||||
.entCode("ent_4587")
|
||||
.ip("123.56.102.11")
|
||||
.port(3310)
|
||||
.build()
|
||||
);
|
||||
return list;
|
||||
}
|
||||
@Bean
|
||||
@Primary
|
||||
public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) {
|
||||
|
||||
Map<Object, Object> dataSourceMap = new HashMap<>();
|
||||
dataSourceInfoList()
|
||||
.stream()
|
||||
.map(entInfo -> DataSourceInfo.hostAndPortBuild(entInfo.getEntCode(),entInfo.getIp(),entInfo.getPort()))
|
||||
.forEach(dataSourceInfo -> {
|
||||
dataSourceMap.put(dataSourceInfo.getKey(), druidDataSourceFactory.create(dataSourceInfo));
|
||||
});
|
||||
//设置动态数据源
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
// dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
|
||||
dynamicDataSource.setTargetDataSources(dataSourceMap);
|
||||
//将数据源信息备份在defineTargetDataSources中
|
||||
dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
|
||||
return dynamicDataSource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.muyu.many.config.contents;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 数据源常量
|
||||
* @Date 2023-8-1 上午 11:02
|
||||
*/
|
||||
public class DatasourceContent {
|
||||
|
||||
public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/car?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
|
||||
|
||||
public final static String USER_NAME = "root";
|
||||
|
||||
public final static String PASSWORD = "root";
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.muyu.many.config.domai.model;
|
||||
|
||||
import com.muyu.common.core.utils.StringUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import static com.muyu.many.config.contents.DatasourceContent.*;
|
||||
|
||||
/**
|
||||
* @ClassName DataSourceInfo
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 14:20
|
||||
*/
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DataSourceInfo {
|
||||
/**
|
||||
* 键
|
||||
*/
|
||||
private String key;
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
|
||||
public static DataSourceInfo hostAndPortBuild(String key,String host,Integer port){
|
||||
return DataSourceInfo.builder()
|
||||
.key(key)
|
||||
.url(StringUtils.format(DATASOURCE_URL, host,port))
|
||||
.password(PASSWORD)
|
||||
.userName(USER_NAME)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.muyu.many.config.domai.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* 企业信息
|
||||
*
|
||||
* @ClassName EntInfo
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 15:02
|
||||
*/
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class EntInfo {
|
||||
private String entCode;
|
||||
private String ip;
|
||||
private Integer port;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.muyu.many.config.factory;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.muyu.many.config.domai.model.DataSourceInfo;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Druid工厂
|
||||
*
|
||||
* @ClassName DruidDataSourceFactory
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 14:14
|
||||
*/
|
||||
|
||||
@Log4j2
|
||||
@Component
|
||||
public class DruidDataSourceFactory {
|
||||
/**
|
||||
* @Description: 根据传递的数据源信息测试数据库连接
|
||||
* @Author AnNan.Wang
|
||||
*/
|
||||
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("{} -> 数据源连接成功", dataSourceInfo.getKey());
|
||||
return druidDataSource;
|
||||
} catch (SQLException throwables) {
|
||||
log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.muyu.many.config.holder;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* 数据源切换处理
|
||||
*
|
||||
* @author Dongzl
|
||||
*/
|
||||
@Slf4j
|
||||
public class DynamicDataSourceHolder {
|
||||
/**
|
||||
* 保存动态数据源名称
|
||||
*/
|
||||
private static final ThreadLocal<String> DYNAMIC_DATASOURCE_KEY = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 设置/切换数据源,决定当前线程使用哪个数据源
|
||||
*/
|
||||
public static void setDynamicDataSourceKey(String key){
|
||||
log.info("数据源切换为:{}",key);
|
||||
DYNAMIC_DATASOURCE_KEY.set(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取动态数据源名称,默认使用mater数据源
|
||||
*/
|
||||
public static String getDynamicDataSourceKey(){
|
||||
String key = DYNAMIC_DATASOURCE_KEY.get();
|
||||
Assert.notNull(key, "请携带数据标识");
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除当前数据源
|
||||
*/
|
||||
public static void removeDynamicDataSourceKey(){
|
||||
log.info("移除数据源:{}",DYNAMIC_DATASOURCE_KEY.get());
|
||||
DYNAMIC_DATASOURCE_KEY.remove();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.muyu.many.config.role;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.muyu.many.config.domai.model.DataSourceInfo;
|
||||
import com.muyu.many.config.holder.DynamicDataSourceHolder;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 动态数据源
|
||||
* 调用AddDefineDataSource组件的addDefineDynamicDataSource()方法,获取原来targetdatasources的map,并将新的数据源信息添加到map中,并替换targetdatasources中的map
|
||||
* 切换数据源时可以使用@DataSource(value = "数据源名称"),或者DynamicDataSourceContextHolder.setContextKey("数据源名称")
|
||||
* @author Dongzl
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DynamicDataSource extends AbstractRoutingDataSource {
|
||||
//备份所有数据源信息,备份的是个 指针 !!!
|
||||
private Map<Object, Object> defineTargetDataSources;
|
||||
|
||||
|
||||
/**
|
||||
* 添加数据源
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void put(String key, DruidDataSource value) {
|
||||
defineTargetDataSources.put(key, value);
|
||||
}
|
||||
/**
|
||||
* 决定当前线程使用哪个数据源
|
||||
*/
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey() {
|
||||
return DynamicDataSourceHolder.getDynamicDataSourceKey();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.muyu.many.server.controller;
|
||||
|
||||
import com.muyu.common.core.domain.Result;
|
||||
import com.muyu.many.config.holder.DynamicDataSourceHolder;
|
||||
import com.muyu.many.server.domain.Enterprise;
|
||||
import com.muyu.many.server.service.EnterpriseService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业表 Controller层
|
||||
*
|
||||
* @ClassName EnterpriseController
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 20:53
|
||||
*/
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/enterprise")
|
||||
public class EnterpriseController {
|
||||
@Autowired
|
||||
private EnterpriseService enterpriseService;
|
||||
|
||||
@GetMapping("/all/{code}")
|
||||
public Result<List<Enterprise>> all(@PathVariable("code") String code){
|
||||
DynamicDataSourceHolder.setDynamicDataSourceKey(code);
|
||||
return enterpriseService.enterpriseList(code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.muyu.many.server.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.muyu.common.core.web.domain.BaseEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 企业表
|
||||
*
|
||||
* @ClassName Enterprise
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 20:47
|
||||
*/
|
||||
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TableName(value = "enterprise")
|
||||
public class Enterprise extends BaseEntity {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id",type = IdType.AUTO)
|
||||
private Long id;
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
private String enterpriseName;
|
||||
/**
|
||||
* 法定代表人
|
||||
*/
|
||||
private String legalPerson;
|
||||
/**
|
||||
* 经营执照凭证号码
|
||||
*/
|
||||
private String businessLicenseNumber;
|
||||
/**
|
||||
* 企业成立时间
|
||||
*/
|
||||
private Date establishmentDate;
|
||||
/**
|
||||
* 经营范围
|
||||
*/
|
||||
private String businessScope;
|
||||
/**
|
||||
* 注册地址
|
||||
*/
|
||||
private String address;
|
||||
/**
|
||||
* 企业联系方式
|
||||
*/
|
||||
private String contactPhone;
|
||||
/**
|
||||
* 公司邮箱
|
||||
*/
|
||||
private String email;
|
||||
/**
|
||||
* 企业当前状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 企业入驻平台时期
|
||||
*/
|
||||
private Date registrationDate;
|
||||
/**
|
||||
* 企业认证id
|
||||
*/
|
||||
private Long certificationId;
|
||||
/**
|
||||
* 认证时间
|
||||
*/
|
||||
private Date authenticationDate;
|
||||
/**
|
||||
* 服务级别
|
||||
*/
|
||||
private Integer serviceLevel;
|
||||
/**
|
||||
* 开通服务id
|
||||
*/
|
||||
private Long open_serverId;
|
||||
/**
|
||||
* 增值服务id
|
||||
*/
|
||||
private Long add_serverId;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.muyu.many.server.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muyu.many.server.domain.Enterprise;
|
||||
|
||||
/**
|
||||
* Enterprise 企业表的Mapper接口层
|
||||
*
|
||||
* @author AnNan.Wang
|
||||
* @ClassName: EnterpriseMapper
|
||||
* @createTime: 2024/6/4 20:58
|
||||
*/
|
||||
public interface EnterpriseMapper extends BaseMapper<Enterprise> {
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.muyu.many.server.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muyu.common.core.domain.Result;
|
||||
import com.muyu.many.server.domain.Enterprise;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Enterprise 企业表Service层接口
|
||||
*
|
||||
* @author AnNan.Wang
|
||||
* @ClassName: EnterpriseService
|
||||
* @createTime: 2024/6/4 20:54
|
||||
*/
|
||||
public interface EnterpriseService extends IService<Enterprise> {
|
||||
Result<List<Enterprise>> enterpriseList(String code);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.muyu.many.server.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.muyu.common.core.domain.Result;
|
||||
import com.muyu.many.server.domain.Enterprise;
|
||||
import com.muyu.many.server.mapper.EnterpriseMapper;
|
||||
import com.muyu.many.server.service.EnterpriseService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Enterprise 企业表的EnterpriseService业务实现层
|
||||
*
|
||||
* @ClassName EnterpriseServiceImpl
|
||||
* @Author AnNan.Wang
|
||||
* @Date 2024/6/4 20:57
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise>
|
||||
implements EnterpriseService{
|
||||
@Autowired
|
||||
private EnterpriseMapper enterpriseMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public Result<List<Enterprise>> enterpriseList(String code) {
|
||||
return Result.success(
|
||||
enterpriseMapper.selectList(null)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue