123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package com.xin.shardingspherejdbcdemo.service.impl;
- import com.google.common.collect.Maps;
- import com.xin.shardingspherejdbcdemo.config.sharding.MyDataSourceConfig;
- import com.xin.shardingspherejdbcdemo.config.sharding.MyDataSourcePropertie;
- import com.xin.shardingspherejdbcdemo.utils.JdbcUtils;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.compress.utils.Sets;
- import org.apache.ibatis.javassist.Modifier;
- import org.apache.shardingsphere.core.rule.ShardingRule;
- import org.apache.shardingsphere.core.rule.TableRule;
- import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
- import org.apache.shardingsphere.underlying.common.rule.DataNode;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.util.StringUtils;
- import javax.annotation.Resource;
- import javax.sql.DataSource;
- import java.lang.reflect.Field;
- import java.sql.SQLException;
- import java.util.*;
- import java.util.concurrent.atomic.AtomicInteger;
- @Service
- @Slf4j
- public class JdbcServiceImpl {
- public boolean createTable() throws SQLException {
- String ip = "192.168.29.131";
- String port = "3306";
- String dbName = "sharding_user";
- String username = "root";
- String password = "123456";
- String tableName = "t_order_2022";
- return JdbcUtils.createTable(ip, port, dbName, username, password, tableName);
- }
- @Resource(name = "shardingDataSource")
- private DataSource dataSource;
- @Autowired
- private MyDataSourceConfig myDataSourceConfig;
- /**
- * 获取数据节点
- */
- private List<DataNode> getDataNodes(MyDataSourcePropertie myDaSoPro, String dataSourceName, String logicTableName) throws SQLException {
- List<DataNode> newDataNodes = new ArrayList<>();
- Calendar date = Calendar.getInstance();
- String year = String.valueOf(date.get(Calendar.YEAR));
- String createTableName = logicTableName + year;
- JdbcUtils.createTable(myDaSoPro.getIp(), myDaSoPro.getPort(), myDaSoPro.getDbname(), myDaSoPro.getUsername(), myDaSoPro.getPassword(), createTableName);
- List<String> tables = JdbcUtils.queryTable(myDaSoPro.getIp(), myDaSoPro.getPort(), myDaSoPro.getDbname(), myDaSoPro.getUsername(), myDaSoPro.getPassword(), logicTableName);
- for (String table : tables) {
- DataNode dataNode = new DataNode(dataSourceName + "." + table);
- newDataNodes.add(dataNode);
- }
- // 扩展点
- return newDataNodes;
- }
- @Transactional
- public void checkDb() {
- Map<String, MyDataSourcePropertie> dataSourceConfig = myDataSourceConfig.getDataSourceConfig();
- try {
- ShardingDataSource shardingDataSource = (ShardingDataSource) dataSource;
- ShardingRule shardingRule = shardingDataSource.getRuntimeContext().getRule();
- //tableRule = shardingRule.getTableRule(dynamicTableName);
- List<TableRule> tableRules = (List<TableRule>) shardingRule.getTableRules();
- Map<String, Map<String, List<DataNode>>> data = new HashMap<>();
- for (TableRule tableRule : tableRules) {
- String logicTableName = tableRule.getLogicTable();
- Collection<String> actualDatasourceNames = tableRule.getActualDatasourceNames();
- Map<String, List<DataNode>> dataSourceMap = new HashMap<>();
- for (String dataSourceName : actualDatasourceNames) {
- List<DataNode> dataNodeList = new ArrayList<>();
- dataSourceMap.put(dataSourceName, dataNodeList);
- data.put(logicTableName, dataSourceMap);
- MyDataSourcePropertie myDataSourcePropertie = dataSourceConfig.get(dataSourceName);
- if (!StringUtils.isEmpty(myDataSourcePropertie)) {
- String shardingDbName = myDataSourcePropertie.getShardingDbName();
- //并且包含需要自动刷新的表
- if (myDataSourcePropertie.getTables().contains(logicTableName)) {
- //获取最近节点
- List<DataNode> newDataNodes = getDataNodes(myDataSourcePropertie, dataSourceName, logicTableName);
- dataNodeList.addAll(newDataNodes);
- }
- }
- }
- }
- for (TableRule tableRule : tableRules) {
- String logicTableName = tableRule.getLogicTable();
- Map<String, List<DataNode>> dataListMap = data.get(logicTableName);
- //刷新数据库jdbc连接信息
- dynamicRefreshDatasourceNew(tableRule, dataListMap);
- }
- } catch (NoSuchFieldException | IllegalAccessException | SQLException e) {
- log.error(String.format("逻辑表:%s 动态分表配置错误!"));
- }
- }
- /**
- * 动态刷新数据源
- */
- private void dynamicRefreshDatasourceNew(TableRule tableRule, Map<String, List<DataNode>> dataListMap)
- throws NoSuchFieldException, IllegalAccessException {
- // 动态刷新:datasourceToTablesMapField
- Map<String, Collection<String>> datasourceToTablesMap = Maps.newHashMap();
- // 获取最新的DataNodes
- List<DataNode> newDataNodesAll = new ArrayList<>();
- // 获取最新的actualTablesAll
- Set<String> actualTablesAll = Sets.newHashSet();
- // 获取最新的dataNodeIndexMap
- Map<DataNode, Integer> dataNodeIndexMap = Maps.newHashMap();
- for (String dataSourceName : dataListMap.keySet()) {
- List<DataNode> newDataNodes = dataListMap.get(dataSourceName);
- Set<String> actualTables = Sets.newHashSet();
- AtomicInteger index = new AtomicInteger(0);
- newDataNodes.forEach(dataNode -> {
- actualTables.add(dataNode.getTableName());
- if (index.intValue() == 0) {
- dataNodeIndexMap.put(dataNode, 0);
- } else {
- dataNodeIndexMap.put(dataNode, index.intValue());
- }
- index.incrementAndGet();
- });
- datasourceToTablesMap.put(dataSourceName, actualTables);
- actualTablesAll.addAll(actualTables);
- newDataNodesAll.addAll(newDataNodes);
- }
- // 动态刷新:actualDataNodesField
- Field actualDataNodesField = TableRule.class.getDeclaredField("actualDataNodes");
- Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(actualDataNodesField, actualDataNodesField.getModifiers() & ~Modifier.FINAL);
- actualDataNodesField.setAccessible(true);
- actualDataNodesField.set(tableRule, newDataNodesAll);
- // 动态刷新:actualTablesField
- Field actualTablesField = TableRule.class.getDeclaredField("actualTables");
- actualTablesField.setAccessible(true);
- actualTablesField.set(tableRule, actualTablesAll);
- // 动态刷新:dataNodeIndexMapField
- Field dataNodeIndexMapField = TableRule.class.getDeclaredField("dataNodeIndexMap");
- dataNodeIndexMapField.setAccessible(true);
- dataNodeIndexMapField.set(tableRule, dataNodeIndexMap);
- // 动态刷新:datasourceToTablesMapField
- Field datasourceToTablesMapField = TableRule.class.getDeclaredField("datasourceToTablesMap");
- datasourceToTablesMapField.setAccessible(true);
- datasourceToTablesMapField.set(tableRule, datasourceToTablesMap);
- }
- }
|