ShardingConfig

This commit is contained in:
wangw 2024-12-30 14:02:26 +08:00
parent b5e8d2514b
commit eca308e06f
21 changed files with 542 additions and 533 deletions

55
pom.xml
View File

@ -35,12 +35,14 @@
<qiniu.version>7.2.23</qiniu.version>
<aliyun.oss.version>3.4.0</aliyun.oss.version>
<qcloud.cos.version>4.4</qcloud.cos.version>
<swagger.version>2.7.0</swagger.version>
<!-- <swagger.version>2.7.0</swagger.version>-->
<swagger.version>2.9.2</swagger.version>
<joda.time.version>2.9.9</joda.time.version>
<gson.version>2.8.5</gson.version>
<fastjson.version>1.2.83</fastjson.version>
<hutool.version>4.6.10</hutool.version>
<lombok.version>1.18.4</lombok.version>
<shardingsphere.version>4.1.1</shardingsphere.version>
<!--wagon plugin 配置-->
<!--<service-path>/work/sz</service-path>
@ -67,6 +69,12 @@
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.274</version>
<exclusions>
<exclusion>
<artifactId>aws-java-sdk-simpleworkflow</artifactId>
<groupId>com.amazonaws</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
@ -183,6 +191,12 @@
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.4.0</version>
<exclusions>
<exclusion>
<artifactId>aliyun-java-sdk-core</artifactId>
<groupId>com.aliyun</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
@ -247,6 +261,13 @@
</exclusion>
</exclusions>
</dependency>
<!--动态数据库切换-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
@ -257,6 +278,23 @@
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<!-- 用于定义sharding-jdbc 分片规则 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-api</artifactId>
<version>${shardingsphere.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>${shardingsphere.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--mssql驱动-->
<dependency>
@ -327,14 +365,25 @@
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>

View File

@ -1,6 +1,7 @@
package com.sqx;
import com.sqx.modules.pay.wuyou.WuyouPay;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@ -18,25 +19,29 @@ import java.util.Map;
public class SqxApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SqxApplication.class, args);
context.getEnvironment().getPropertySources().forEach(source -> {
if (source.getName().contains("application-dev.yml") || source.getName().contains("application-prod.yml")) {
if (source.getSource() instanceof Map) {
((Map<String, Object>) source.getSource()).forEach((key, value) -> {
System.out.println(key + ": " + value);
if ("pay.orderNotifyUrl".equals(key)) {
WuyouPay.setNotifyUrl(value.toString());
}
if ("pay.extractNotifyUrl".equals(key)) {
WuyouPay.setExtractNotifyUrl(value.toString());
}
if ("pay.h5BaseUrl".equals(key)) {
WuyouPay.setH5BaseUrl(value.toString());
}
});
}
}
});
SpringApplication application = new SpringApplication(SqxApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
// ConfigurableApplicationContext context = SpringApplication.run(SqxApplication.class, args);
// context.getEnvironment().getPropertySources().forEach(source -> {
// if (source.getName().contains("application-dev.yml") || source.getName().contains("application-prod.yml")) {
// if (source.getSource() instanceof Map) {
// ((Map<String, Object>) source.getSource()).forEach((key, value) -> {
// System.out.println(key + ": " + value);
// if ("pay.orderNotifyUrl".equals(key)) {
// WuyouPay.setNotifyUrl(value.toString());
// }
// if ("pay.extractNotifyUrl".equals(key)) {
// WuyouPay.setExtractNotifyUrl(value.toString());
// }
// if ("pay.h5BaseUrl".equals(key)) {
// WuyouPay.setH5BaseUrl(value.toString());
// }
// });
// }
// }
// });
System.out.println("(♥◠‿◠)ノ゙ 短剧系统启动成功 ლ(´ڡ`ლ)゙ \n"+
" _ \n" +
" | | \n" +

View File

@ -1,5 +1,6 @@
package com.sqx.config;
import com.sqx.common.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
@ -70,4 +71,10 @@ public class RedisConfig {
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
@Bean
public RedisUtils redisUtils() {
// 根据实际情况初始化RedisUtils实例可能需要传入相关配置参数如Redis连接信息等
return new RedisUtils();
}
}

View File

@ -0,0 +1,153 @@
package com.sqx.config;
import com.sqx.sharding.MasterSlaveRules;
import com.sqx.sharding.ShardingDataBase;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
/**
* sharding-jdbc 配置文件
*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.shardingsphere")
public class ShardingConfig {
/**
* 读取数据源信息
*/
private Map<String, ShardingDataBase> datasource;
/**
* 读写分离的配置
*/
private Map<String, MasterSlaveRules> masterSlaveRules;
/**
* 显示sharding-jdbc的sql
*/
private String showSql;
/**
* 中心库的节点
*/
private String centerTablesDataNode;
@Value("${center-tables}")
private String tableNamesAsString;
/**
* 中心表,不进行分库操作
*/
// @Value("${center-tables}")
private Set<String> centerTables;
@PostConstruct
public void init() {
// 使用换行符进行分割然后去除空白字符收集到Set集合中
centerTables = Arrays.stream(tableNamesAsString.split(","))
.map(String::trim)
.collect(Collectors.toSet());
}
/**
* 配置sharding-jdbc数据源
*/
@Bean
public DataSource dataSource() throws SQLException {
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
// 配置数据库主从
shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs());
// 配置表的切分策略
shardingRuleConfig.setTableRuleConfigs(addTableRuleConfigs());
// 配置是否显示sql
// Properties props = new Properties();
// props.put("sql.show", true);
// 配置数据源
Map<String, DataSource> dataSourceMap = getShardingDataBase();
return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, null);
// return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props);
}
/**
* 配置
*/
private Set<TableRuleConfiguration> addTableRuleConfigs() {
Set<TableRuleConfiguration> sets = new HashSet<>();
for (String centerTable : centerTables) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable,
String.format(centerTablesDataNode, centerTable));
sets.add(tableRuleConfig);
}
// // 定义区域表的分库规则
// InlineShardingStrategyConfiguration databaseShardingStrategyConfig = new InlineShardingStrategyConfiguration(
// regionTablesShardingDatabaseColumn, regionTablesShardingDatabaseAlgorithm);
// for (String regionTable : regionTables) {
// TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
// tableRuleConfig.setDatabaseShardingStrategyConfig(databaseShardingStrategyConfig);
// sets.add(tableRuleConfig);
// }
return sets;
}
/**
* 配置数据源
*/
private Map<String, DataSource> getShardingDataBase() {
String testQuery = "SELECT 1";
Map<String, DataSource> map = new HashMap<>();
datasource.forEach((datasourceName, shardingDataBase) -> {
HikariConfig config = new HikariConfig();
config.setDriverClassName(shardingDataBase.getDriverClassName());
config.setJdbcUrl(shardingDataBase.getJdbcUrl());
config.setUsername(shardingDataBase.getUsername());
config.setPassword(shardingDataBase.getPassword());
config.setPoolName(datasourceName);
config.setMinimumIdle(shardingDataBase.getMinimumIdle());
config.setMaximumPoolSize(shardingDataBase.getMaximumPoolSize());
config.setIdleTimeout(shardingDataBase.getIdleTimeout());
config.setMaxLifetime(shardingDataBase.getMaxLifetime());
config.setConnectionTimeout(shardingDataBase.getConnectionTimeout());
config.setConnectionTestQuery(testQuery);
map.put(datasourceName, new HikariDataSource(config));
});
return map;
}
/**
* 配置读写分离
*/
private Set<MasterSlaveRuleConfiguration> masterSlaveRuleConfigs() {
Set<MasterSlaveRuleConfiguration> sets = new HashSet<>();
masterSlaveRules.forEach((databaseName, masterSlaveRules) -> {
MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration(databaseName,
masterSlaveRules.getMasterDataSourceName(), masterSlaveRules.getSlaveDataSourceNames());
System.out.println("写入"+masterSlaveRules.getMasterDataSourceName());
System.out.println("读出"+masterSlaveRules.getSlaveDataSourceNames());
sets.add(masterSlaveRuleConfig);
});
return sets;
}
}

View File

@ -0,0 +1,67 @@
package com.sqx.config;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.DataSourceUnwrapper;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Collection;
/**
* @author wxkj0012
*/
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter({MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class,
SimpleMetricsExportAutoConfiguration.class})
@ConditionalOnClass({DataSource.class, MeterRegistry.class})
@ConditionalOnBean({DataSource.class, MeterRegistry.class})
@Slf4j
public class ShardingDataSourcePoolMetricsAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ShardingDataSource.class, HikariDataSource.class})
static class ShardingDataSourceMetricsConfiguration {
private final MeterRegistry registry;
ShardingDataSourceMetricsConfiguration(MeterRegistry registry) {
this.registry = registry;
}
@Autowired
void bindMetricsRegistryToHikariDataSources(Collection<DataSource> dataSources) {
for (DataSource dataSource : dataSources) {
ShardingDataSource shardingDataSource = DataSourceUnwrapper.unwrap(dataSource, ShardingDataSource.class);
Collection<DataSource> shardDataSources = shardingDataSource.getDataSourceMap().values();
for (DataSource ds : shardDataSources) {
HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(ds, HikariDataSource.class);
if (hikariDataSource != null) {
bindMetricsRegistryToHikariDataSource(hikariDataSource);
}
}
}
}
private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari) {
if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) {
try {
hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(this.registry));
} catch (Exception ex) {
log.warn("Failed to bind Hikari metrics: {}}", ex.getMessage());
}
}
}
}
}

View File

@ -1,58 +1,85 @@
package com.sqx.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Value("${swagger.enabled}")
private boolean enabled;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(enabled)
.apiInfo(apiInfo())
.select()
//加了ApiOperation注解的类才生成接口文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//包下的类才生成接口文档
//.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(security());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("")
.description("sqx-fast文档")
.termsOfServiceUrl("")
.version("3.0.0")
.build();
}
private List<ApiKey> security() {
return newArrayList(
new ApiKey("token", "token", "header")
);
}
}
//package com.sqx.config;
//
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Profile;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//import springfox.documentation.builders.ApiInfoBuilder;
//import springfox.documentation.builders.PathSelectors;
//import springfox.documentation.builders.RequestHandlerSelectors;
//import springfox.documentation.service.ApiInfo;
//import springfox.documentation.service.ApiKey;
//import springfox.documentation.spi.DocumentationType;
//import springfox.documentation.spring.web.plugins.Docket;
//import springfox.documentation.swagger2.annotations.EnableSwagger2;
//
//import java.util.List;
//
//import static com.google.common.collect.Lists.newArrayList;
//
////@Configuration
////@EnableSwagger2
////public class SwaggerConfig implements WebMvcConfigurer {
////
//// @Value("${swagger.enabled}")
//// private boolean enabled;
////
//// @Bean
//// public Docket createRestApi() {
//// return new Docket(DocumentationType.SWAGGER_2)
//// .enable(enabled)
//// .apiInfo(apiInfo())
//// .select()
//// //加了ApiOperation注解的类才生成接口文档
//// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//// //包下的类才生成接口文档
//// //.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
//// .paths(PathSelectors.any())
//// .build()
//// .securitySchemes(security());
//// }
////
//// private ApiInfo apiInfo() {
//// return new ApiInfoBuilder()
//// .title("")
//// .description("sqx-fast文档")
//// .termsOfServiceUrl("")
//// .version("3.0.0")
//// .build();
//// }
////
//// private List<ApiKey> security() {
//// return newArrayList(
//// new ApiKey("token", "token", "header")
//// );
//// }
////
////}
//
//@Configuration
//@EnableSwagger2
//@Profile({"local", "dev"})
//public class SwaggerConfig {
//
// @Bean
// public Docket api() {
// return new Docket(DocumentationType.SWAGGER_2)
// .apiInfo(apiInfo())
// .select()
// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .paths(PathSelectors.any())
// .build();
// }
//
// private ApiInfo apiInfo() {
// return new ApiInfoBuilder()
// .title("悠车位后台API接口文档")
// .description("悠车位服务端后台API接口文档")
// .version("1.0")
// .build();
// }
//}

View File

@ -1,14 +0,0 @@
package com.sqx.datasource.annotation;
import java.lang.annotation.*;
/**
* 多数据源注解
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource {
String value() default "";
}

View File

@ -1,61 +0,0 @@
package com.sqx.datasource.aspect;
import com.sqx.datasource.annotation.DataSource;
import com.sqx.datasource.config.DynamicContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 多数据源切面处理类
*/
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DataSourceAspect {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.sqx.datasource.annotation.DataSource) " +
"|| @within(com.sqx.datasource.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Class targetClass = point.getTarget().getClass();
Method method = signature.getMethod();
DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
DataSource methodDataSource = method.getAnnotation(DataSource.class);
if(targetDataSource != null || methodDataSource != null){
String value;
if(methodDataSource != null){
value = methodDataSource.value();
}else {
value = targetDataSource.value();
}
DynamicContextHolder.push(value);
logger.debug("set datasource is {}", value);
}
try {
return point.proceed();
} finally {
DynamicContextHolder.poll();
logger.debug("clean datasource");
}
}
}

View File

@ -1,47 +0,0 @@
package com.sqx.datasource.config;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* 多数据源上下文
*/
public class DynamicContextHolder {
@SuppressWarnings("unchecked")
private static final ThreadLocal<Deque<String>> CONTEXT_HOLDER = new ThreadLocal() {
@Override
protected Object initialValue() {
return new ArrayDeque();
}
};
/**
* 获得当前线程数据源
*
* @return 数据源名称
*/
public static String peek() {
return CONTEXT_HOLDER.get().peek();
}
/**
* 设置当前线程数据源
*
* @param dataSource 数据源名称
*/
public static void push(String dataSource) {
CONTEXT_HOLDER.get().push(dataSource);
}
/**
* 清空当前线程数据源
*/
public static void poll() {
Deque<String> deque = CONTEXT_HOLDER.get();
deque.poll();
if (deque.isEmpty()) {
CONTEXT_HOLDER.remove();
}
}
}

View File

@ -1,15 +0,0 @@
package com.sqx.datasource.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 多数据源
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicContextHolder.peek();
}
}

View File

@ -1,53 +0,0 @@
package com.sqx.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.sqx.datasource.properties.DataSourceProperties;
import com.sqx.datasource.properties.DynamicDataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* 配置多数据源
*/
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDataSourceConfig {
@Autowired
private DynamicDataSourceProperties properties;
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(getDynamicDataSource());
//默认数据源
DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
return dynamicDataSource;
}
private Map<Object, Object> getDynamicDataSource(){
Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
dataSourcePropertiesMap.forEach((k, v) -> {
DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
targetDataSources.put(k, druidDataSource);
});
return targetDataSources;
}
}

View File

@ -1,44 +0,0 @@
package com.sqx.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.sqx.datasource.properties.DataSourceProperties;
import java.sql.SQLException;
/**
* DruidDataSource
*
*/
public class DynamicDataSourceFactory {
public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(properties.getDriverClassName());
druidDataSource.setUrl(properties.getUrl());
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setInitialSize(properties.getInitialSize());
druidDataSource.setMaxActive(properties.getMaxActive());
druidDataSource.setMinIdle(properties.getMinIdle());
druidDataSource.setMaxWait(properties.getMaxWait());
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
druidDataSource.setValidationQuery(properties.getValidationQuery());
druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements());
try {
druidDataSource.setFilters(properties.getFilters());
druidDataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
}

View File

@ -1,192 +0,0 @@
package com.sqx.datasource.properties;
/**
* 多数据源属性
*
*/
public class DataSourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
/**
* Druid默认参数
*/
private int initialSize = 2;
private int maxActive = 10;
private int minIdle = -1;
private long maxWait = 60 * 1000L;
private long timeBetweenEvictionRunsMillis = 60 * 1000L;
private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
private String validationQuery = "select 1";
private int validationQueryTimeout = -1;
private boolean testOnBorrow = false;
private boolean testOnReturn = false;
private boolean testWhileIdle = true;
private boolean poolPreparedStatements = false;
private int maxOpenPreparedStatements = -1;
private boolean sharePreparedStatements = false;
private String filters = "stat,wall";
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public long getMaxEvictableIdleTimeMillis() {
return maxEvictableIdleTimeMillis;
}
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public int getValidationQueryTimeout() {
return validationQueryTimeout;
}
public void setValidationQueryTimeout(int validationQueryTimeout) {
this.validationQueryTimeout = validationQueryTimeout;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxOpenPreparedStatements() {
return maxOpenPreparedStatements;
}
public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
this.maxOpenPreparedStatements = maxOpenPreparedStatements;
}
public boolean isSharePreparedStatements() {
return sharePreparedStatements;
}
public void setSharePreparedStatements(boolean sharePreparedStatements) {
this.sharePreparedStatements = sharePreparedStatements;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
}

View File

@ -1,22 +0,0 @@
package com.sqx.datasource.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 多数据源属性
*/
@ConfigurationProperties(prefix = "dynamic")
public class DynamicDataSourceProperties {
private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
public Map<String, DataSourceProperties> getDatasource() {
return datasource;
}
public void setDatasource(Map<String, DataSourceProperties> datasource) {
this.datasource = datasource;
}
}

View File

@ -107,8 +107,8 @@ public class AppController {
userEntity.setUserId(userId);
old.setZhiFuBao(userEntity.getZhiFuBao());
old.setZhiFuBaoName(userEntity.getZhiFuBaoName());
boolean bool = userService.updateById(userEntity);
// 去除首绑支付宝奖励
// boolean bool = userService.updateById(userEntity);
// if (bool && isFirstBind) {
// userService.firstBindAwardsMoney(old);
// }

View File

@ -47,7 +47,7 @@ public class AppCommonController {
" 20后台管理平台域名配置\n" +
" 22拼多多优惠券地址")
@ResponseBody
@Login
// @Login
public Result getCommonList(@PathVariable Integer type) {
return commonService.findByType(type);
}

View File

@ -0,0 +1,22 @@
package com.sqx.sharding;
import lombok.Data;
import java.util.List;
/**
* 读写分离配置
*/
@Data
public class MasterSlaveRules {
/**
* 写库
*/
private String masterDataSourceName;
/**
* 读库
*/
private List<String> slaveDataSourceNames;
}

View File

@ -0,0 +1,61 @@
package com.sqx.sharding;
import lombok.Data;
/**
* 用于注入sharding-jdbc的值
*/
@Data
public class ShardingDataBase {
/**
* 连接池
*/
private String type;
/**
* 驱动名称
*/
private String driverClassName;
/**
* 数据库地址
*/
private String jdbcUrl;
/**
* 数据库用户名
*/
private String username;
/**
* 数据库密码
*/
private String password;
/**
* 最小空闲连接默认值10小于0或大于maximum-pool-size都会重置为maximum-pool-size
*/
private int minimumIdle;
/**
* 最大连接数小于等于0会被重置为默认值10大于零小于1会被重置为minimum-idle的值
*/
private int maximumPoolSize;
/**
* 空闲连接超时时间默认值60000010分钟大于等于max-lifetime且max-lifetime>0会被重置为0不等于0且小于10秒会被重置为10秒
*/
private int idleTimeout;
/**
* 连接最大存活时间.不等于0且小于30秒会被重置为默认值30分钟.设置应该比mysql设置的超时时间短
*/
private int maxLifetime;
/**
* 连接超时时间:毫秒小于250毫秒否则被重置为默认值30秒
*/
private int connectionTimeout;
}

View File

@ -0,0 +1,61 @@
# 数据源的一些配置
driver-class-name: com.mysql.cj.jdbc.Driver
# 最小空闲连接默认值10小于0或大于maximum-pool-size都会重置为maximum-pool-size
minimum-idle: 5
# 最大连接数小于等于0会被重置为默认值10大于零小于1会被重置为minimum-idle的值
maximum-pool-size: 15
# 空闲连接超时时间默认值60000010分钟大于等于max-lifetime且max-lifetime>0会被重置为0不等于0且小于10秒会被重置为10秒。
idle-timeout: 30000
# 连接最大存活时间.不等于0且小于30秒会被重置为默认值30分钟.设置应该比mysql设置的超时时间短
max-lifetime: 30000
# 连接超时时间:毫秒小于250毫秒否则被重置为默认值30秒
connection-timeout: 30000
spring:
# sharding-jdbc 配置
shardingsphere:
center-tables-data-node: duanju.%s
# 显示sharding-jdbc改写的sql语句
show-sql: true
# 数据源名称
datasource:
# 数据源配置begin
master-0:
# slave-0:
driver-class-name: ${driver-class-name}
jdbc-url: jdbc:mysql://rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
username: video_user
password: VideoUser@1
minimum-idle: ${minimum-idle}
maximum-pool-size: ${maximum-pool-size}
idle-timeout: ${idle-timeout}
max-lifetime: ${max-lifetime}
connection-timeout: ${connection-timeout}
slave-0:
# master-0:
driver-class-name: ${driver-class-name}
jdbc-url: jdbc:mysql://47.122.26.160:3306/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
username: root
password: 0fd6497c308ccfa8
minimum-idle: ${minimum-idle}
maximum-pool-size: ${maximum-pool-size}
idle-timeout: ${idle-timeout}
max-lifetime: ${max-lifetime}
connection-timeout: ${connection-timeout}
# 数据源配置end
# 读写分离配置begin
master-slave-rules:
#数据源
duanju:
master-data-source-name: master-0
slave-data-source-names: slave-0
# - master-0
# - slave-0
swagger:
enabled: true
pay:
h5BaseUrl: https://video-h5.hnsiyao.cn/me/detail/detail?allId=
orderNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/notify
extractNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/extractNotify

View File

@ -0,0 +1 @@
center-tables=activity,app,banner,cash_out,comment_good,common_info,complet_award,coupon,coupon_user,course,course_classification,course_collect,course_comment,course_details,course_user,disc_spinning,disc_spinning_amount,disc_spinning_record,help_classify,help_word,invite,invite_award,invite_money,message_info,msg,orders,pay_classify,pay_details,qrtz_blob_triggers,qrtz_calendars,qrtz_cron_triggers,qrtz_fired_triggers,qrtz_job_details,qrtz_locks,qrtz_paused_trigger_grps,qrtz_scheduler_state,qrtz_simple_triggers,qrtz_simprop_triggers,qrtz_triggers,schedule_job,schedule_job_log,sdk_info,sdk_type,search,sys_captcha,sys_config,sys_dict,sys_log,sys_menu,sys_oss,sys_role,sys_role_menu,sys_user,sys_user_role,sys_user_token,task_center,task_center_record,task_center_reward,tb_user,uni_ad_callback_record,url_address,user_integral,user_integral_details,user_money,user_money_details,user_prize_exchange,user_sign_record,user_vip,vip_details

View File

@ -20,7 +20,7 @@ spring:
allow-bean-definition-overriding: true
# 环境 dev|test|prod
profiles:
active: dev
active: local
# jackson时间格式化
jackson:
time-zone: GMT+8
@ -45,10 +45,14 @@ spring:
min-idle: 5 # 连接池中的最小空闲连接
mvc:
throw-exception-if-no-handler-found: true
pathmatch:
matching-strategy: ant_path_matcher
# pathmatch:
# matching-strategy: ant_path_matcher
management:
health:
db:
enabled: false #关闭数据库健康检查isV
#mybatis
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml