✨ 添加新特性。pigx 动态切换数据源,为后期提供Online开发、数据同步以及读写分离做准备

This commit is contained in:
Lucky committed 2019-05-21 23:57:40 +08:00
1 parent 6eaa933fde
commit 896dbdeb40
12 files changed
+221 -15

No files matched your search

@@ -1,21 +0,0 @@
package com.pig4cloud.pigx.codegen.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2019-05-14
* <p>
* 参考DruidDataSourceWrapper
*/
@Data
@Component
@ConfigurationProperties("spring.datasource.druid")
public class DruidDataSourceProperties {
private String username;
private String password;
private String url;
private String driverClassName;
}
@@ -1,25 +0,0 @@
package com.pig4cloud.pigx.codegen.config;
import com.pig4cloud.pigx.codegen.util.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @author lengleng
* @date 2019-03-31
* <p>
* 动态数据源类
*/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 指定路由Key
*
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceType();
}
}
@@ -1,101 +0,0 @@
package com.pig4cloud.pigx.codegen.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.mysql.cj.jdbc.Driver;
import com.pig4cloud.pigx.codegen.util.DataSourceConstants;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* @author lengleng
* @date 2019-03-31
* <p>
* 动态数据源切换配置
*/
@Slf4j
@Configuration
@AllArgsConstructor
public class DynamicDataSourceConfig implements TransactionManagementConfigurer {
private final Map<Object, Object> dataSourceMap = new HashMap<>(8);
private final DruidDataSourceProperties dataSourceProperties;
private final StringEncryptor stringEncryptor;
@Bean("dynamicDataSource")
public DynamicDataSource dataSource() {
DynamicDataSource ds = new DynamicDataSource();
DruidDataSource cads = new DruidDataSource();
cads.setUrl(dataSourceProperties.getUrl());
cads.setDriverClassName(dataSourceProperties.getDriverClassName());
cads.setUsername(dataSourceProperties.getUsername());
cads.setPassword(dataSourceProperties.getPassword());
ds.setDefaultTargetDataSource(cads);
dataSourceMap.put(0, cads);
ds.setTargetDataSources(dataSourceMap);
return ds;
}
/**
* 组装默认配置的数据源,查询数据库配置
*/
@PostConstruct
public void init() {
DriverManagerDataSource dds = new DriverManagerDataSource();
dds.setUrl(dataSourceProperties.getUrl());
dds.setDriverClassName(dataSourceProperties.getDriverClassName());
dds.setUsername(dataSourceProperties.getUsername());
dds.setPassword(dataSourceProperties.getPassword());
List<Map<String, Object>> dbList = new JdbcTemplate(dds).queryForList(DataSourceConstants.QUERY_DS_SQL);
log.info("开始 -> 初始化动态数据源");
Optional.of(dbList).ifPresent(list -> list.forEach(db -> {
log.info("数据源:{}", db.get(DataSourceConstants.DS_NAME));
DruidDataSource ds = new DruidDataSource();
ds.setUrl(String.valueOf(db.get(DataSourceConstants.DS_JDBC_URL)));
ds.setDriverClassName(Driver.class.getName());
ds.setUsername((String) db.get(DataSourceConstants.DS_USER_NAME));
String decPwd = stringEncryptor.decrypt((String) db.get(DataSourceConstants.DS_USER_PWD));
ds.setPassword(decPwd);
dataSourceMap.put(db.get(DataSourceConstants.DS_ROUTE_KEY), ds);
}));
log.info("完毕 -> 初始化动态数据源,共计 {} 条", dataSourceMap.size());
}
/**
* 重新加载数据源配置
*/
public Boolean reload() {
init();
DynamicDataSource dataSource = dataSource();
dataSource.setTargetDataSources(dataSourceMap);
dataSource.afterPropertiesSet();
return Boolean.FALSE;
}
@Bean
public PlatformTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource());
}
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager();
}
}
@@ -1,40 +0,0 @@
package com.pig4cloud.pigx.codegen.util;
/**
* @author lengleng
* @date 2019-04-01
* <p>
* 数据源相关常量
*/
public interface DataSourceConstants {
/**
* 查询数据源的SQL
*/
String QUERY_DS_SQL = "select * from sys_datasource_conf where del_flag = 0";
/**
* 动态路由KEY
*/
String DS_ROUTE_KEY = "id";
/**
* 数据源名称
*/
String DS_NAME = "name";
/**
* jdbcurl
*/
String DS_JDBC_URL = "url";
/**
* 用户名
*/
String DS_USER_NAME = "username";
/**
* 密码
*/
String DS_USER_PWD = "password";
}
@@ -1,26 +0,0 @@
package com.pig4cloud.pigx.codegen.util;
import lombok.experimental.UtilityClass;
/**
* @author lengleng
* @date 2019-03-31
* <p>
* 保存上线文中数据库路由
*/
@UtilityClass
public class DynamicDataSourceContextHolder {
private final ThreadLocal<Integer> CONTEXT_HOLDER = new ThreadLocal<>();
public void setDataSourceType(Integer dataSourceType) {
CONTEXT_HOLDER.set(dataSourceType);
}
public Integer getDataSourceType() {
return CONTEXT_HOLDER.get();
}
public void clearDataSourceType() {
CONTEXT_HOLDER.remove();
}
}