JdbcServiceImpl.java 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package com.xin.shardingspherejdbcdemo.service.impl;
  2. import com.google.common.collect.Maps;
  3. import com.xin.shardingspherejdbcdemo.config.sharding.MyDataSourceConfig;
  4. import com.xin.shardingspherejdbcdemo.config.sharding.MyDataSourcePropertie;
  5. import com.xin.shardingspherejdbcdemo.utils.JdbcUtils;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.apache.commons.compress.utils.Sets;
  8. import org.apache.ibatis.javassist.Modifier;
  9. import org.apache.shardingsphere.core.rule.ShardingRule;
  10. import org.apache.shardingsphere.core.rule.TableRule;
  11. import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
  12. import org.apache.shardingsphere.underlying.common.rule.DataNode;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Service;
  15. import org.springframework.transaction.annotation.Transactional;
  16. import org.springframework.util.StringUtils;
  17. import javax.annotation.Resource;
  18. import javax.sql.DataSource;
  19. import java.lang.reflect.Field;
  20. import java.sql.SQLException;
  21. import java.util.*;
  22. import java.util.concurrent.atomic.AtomicInteger;
  23. @Service
  24. @Slf4j
  25. public class JdbcServiceImpl {
  26. public boolean createTable() throws SQLException {
  27. String ip = "192.168.29.131";
  28. String port = "3306";
  29. String dbName = "sharding_user";
  30. String username = "root";
  31. String password = "123456";
  32. String tableName = "t_order_2022";
  33. return JdbcUtils.createTable(ip, port, dbName, username, password, tableName);
  34. }
  35. @Resource(name = "shardingDataSource")
  36. private DataSource dataSource;
  37. @Autowired
  38. private MyDataSourceConfig myDataSourceConfig;
  39. /**
  40. * 获取数据节点
  41. */
  42. private List<DataNode> getDataNodes(MyDataSourcePropertie myDaSoPro, String dataSourceName, String logicTableName) throws SQLException {
  43. List<DataNode> newDataNodes = new ArrayList<>();
  44. Calendar date = Calendar.getInstance();
  45. String year = String.valueOf(date.get(Calendar.YEAR));
  46. String createTableName = logicTableName + year;
  47. JdbcUtils.createTable(myDaSoPro.getIp(), myDaSoPro.getPort(), myDaSoPro.getDbname(), myDaSoPro.getUsername(), myDaSoPro.getPassword(), createTableName);
  48. List<String> tables = JdbcUtils.queryTable(myDaSoPro.getIp(), myDaSoPro.getPort(), myDaSoPro.getDbname(), myDaSoPro.getUsername(), myDaSoPro.getPassword(), logicTableName);
  49. for (String table : tables) {
  50. DataNode dataNode = new DataNode(dataSourceName + "." + table);
  51. newDataNodes.add(dataNode);
  52. }
  53. // 扩展点
  54. return newDataNodes;
  55. }
  56. @Transactional
  57. public void checkDb() {
  58. Map<String, MyDataSourcePropertie> dataSourceConfig = myDataSourceConfig.getDataSourceConfig();
  59. try {
  60. ShardingDataSource shardingDataSource = (ShardingDataSource) dataSource;
  61. ShardingRule shardingRule = shardingDataSource.getRuntimeContext().getRule();
  62. //tableRule = shardingRule.getTableRule(dynamicTableName);
  63. List<TableRule> tableRules = (List<TableRule>) shardingRule.getTableRules();
  64. Map<String, Map<String, List<DataNode>>> data = new HashMap<>();
  65. for (TableRule tableRule : tableRules) {
  66. String logicTableName = tableRule.getLogicTable();
  67. Collection<String> actualDatasourceNames = tableRule.getActualDatasourceNames();
  68. Map<String, List<DataNode>> dataSourceMap = new HashMap<>();
  69. for (String dataSourceName : actualDatasourceNames) {
  70. List<DataNode> dataNodeList = new ArrayList<>();
  71. dataSourceMap.put(dataSourceName, dataNodeList);
  72. data.put(logicTableName, dataSourceMap);
  73. MyDataSourcePropertie myDataSourcePropertie = dataSourceConfig.get(dataSourceName);
  74. if (!StringUtils.isEmpty(myDataSourcePropertie)) {
  75. String shardingDbName = myDataSourcePropertie.getShardingDbName();
  76. //并且包含需要自动刷新的表
  77. if (myDataSourcePropertie.getTables().contains(logicTableName)) {
  78. //获取最近节点
  79. List<DataNode> newDataNodes = getDataNodes(myDataSourcePropertie, dataSourceName, logicTableName);
  80. dataNodeList.addAll(newDataNodes);
  81. }
  82. }
  83. }
  84. }
  85. for (TableRule tableRule : tableRules) {
  86. String logicTableName = tableRule.getLogicTable();
  87. Map<String, List<DataNode>> dataListMap = data.get(logicTableName);
  88. //刷新数据库jdbc连接信息
  89. dynamicRefreshDatasourceNew(tableRule, dataListMap);
  90. }
  91. } catch (NoSuchFieldException | IllegalAccessException | SQLException e) {
  92. log.error(String.format("逻辑表:%s 动态分表配置错误!"));
  93. }
  94. }
  95. /**
  96. * 动态刷新数据源
  97. */
  98. private void dynamicRefreshDatasourceNew(TableRule tableRule, Map<String, List<DataNode>> dataListMap)
  99. throws NoSuchFieldException, IllegalAccessException {
  100. // 动态刷新:datasourceToTablesMapField
  101. Map<String, Collection<String>> datasourceToTablesMap = Maps.newHashMap();
  102. // 获取最新的DataNodes
  103. List<DataNode> newDataNodesAll = new ArrayList<>();
  104. // 获取最新的actualTablesAll
  105. Set<String> actualTablesAll = Sets.newHashSet();
  106. // 获取最新的dataNodeIndexMap
  107. Map<DataNode, Integer> dataNodeIndexMap = Maps.newHashMap();
  108. for (String dataSourceName : dataListMap.keySet()) {
  109. List<DataNode> newDataNodes = dataListMap.get(dataSourceName);
  110. Set<String> actualTables = Sets.newHashSet();
  111. AtomicInteger index = new AtomicInteger(0);
  112. newDataNodes.forEach(dataNode -> {
  113. actualTables.add(dataNode.getTableName());
  114. if (index.intValue() == 0) {
  115. dataNodeIndexMap.put(dataNode, 0);
  116. } else {
  117. dataNodeIndexMap.put(dataNode, index.intValue());
  118. }
  119. index.incrementAndGet();
  120. });
  121. datasourceToTablesMap.put(dataSourceName, actualTables);
  122. actualTablesAll.addAll(actualTables);
  123. newDataNodesAll.addAll(newDataNodes);
  124. }
  125. // 动态刷新:actualDataNodesField
  126. Field actualDataNodesField = TableRule.class.getDeclaredField("actualDataNodes");
  127. Field modifiersField = Field.class.getDeclaredField("modifiers");
  128. modifiersField.setAccessible(true);
  129. modifiersField.setInt(actualDataNodesField, actualDataNodesField.getModifiers() & ~Modifier.FINAL);
  130. actualDataNodesField.setAccessible(true);
  131. actualDataNodesField.set(tableRule, newDataNodesAll);
  132. // 动态刷新:actualTablesField
  133. Field actualTablesField = TableRule.class.getDeclaredField("actualTables");
  134. actualTablesField.setAccessible(true);
  135. actualTablesField.set(tableRule, actualTablesAll);
  136. // 动态刷新:dataNodeIndexMapField
  137. Field dataNodeIndexMapField = TableRule.class.getDeclaredField("dataNodeIndexMap");
  138. dataNodeIndexMapField.setAccessible(true);
  139. dataNodeIndexMapField.set(tableRule, dataNodeIndexMap);
  140. // 动态刷新:datasourceToTablesMapField
  141. Field datasourceToTablesMapField = TableRule.class.getDeclaredField("datasourceToTablesMap");
  142. datasourceToTablesMapField.setAccessible(true);
  143. datasourceToTablesMapField.set(tableRule, datasourceToTablesMap);
  144. }
  145. }