Selaa lähdekoodia

完成动态按时间分库分表

赵冬冬 3 vuotta sitten
vanhempi
sitoutus
6cf4cf0080

+ 87 - 17
src/main/java/com/xin/shardingspherejdbcdemo/service/impl/JdbcServiceImpl.java

@@ -44,6 +44,24 @@ public class JdbcServiceImpl {
     @Autowired
     @Autowired
     private MyDataSourceConfig myDataSourceConfig;
     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
     @Transactional
     public void checkDb() {
     public void checkDb() {
         Map<String, MyDataSourcePropertie> dataSourceConfig = myDataSourceConfig.getDataSourceConfig();
         Map<String, MyDataSourcePropertie> dataSourceConfig = myDataSourceConfig.getDataSourceConfig();
@@ -52,46 +70,98 @@ public class JdbcServiceImpl {
             ShardingRule shardingRule = shardingDataSource.getRuntimeContext().getRule();
             ShardingRule shardingRule = shardingDataSource.getRuntimeContext().getRule();
             //tableRule = shardingRule.getTableRule(dynamicTableName);
             //tableRule = shardingRule.getTableRule(dynamicTableName);
             List<TableRule> tableRules = (List<TableRule>) shardingRule.getTableRules();
             List<TableRule> tableRules = (List<TableRule>) shardingRule.getTableRules();
-
+            Map<String, Map<String, List<DataNode>>> data = new HashMap<>();
             for (TableRule tableRule : tableRules) {
             for (TableRule tableRule : tableRules) {
                 String logicTableName = tableRule.getLogicTable();
                 String logicTableName = tableRule.getLogicTable();
                 Collection<String> actualDatasourceNames = tableRule.getActualDatasourceNames();
                 Collection<String> actualDatasourceNames = tableRule.getActualDatasourceNames();
+                Map<String, List<DataNode>> dataSourceMap = new HashMap<>();
                 for (String dataSourceName : actualDatasourceNames) {
                 for (String dataSourceName : actualDatasourceNames) {
+                    List<DataNode> dataNodeList = new ArrayList<>();
+                    dataSourceMap.put(dataSourceName, dataNodeList);
+                    data.put(logicTableName, dataSourceMap);
                     MyDataSourcePropertie myDataSourcePropertie = dataSourceConfig.get(dataSourceName);
                     MyDataSourcePropertie myDataSourcePropertie = dataSourceConfig.get(dataSourceName);
                     if (!StringUtils.isEmpty(myDataSourcePropertie)) {
                     if (!StringUtils.isEmpty(myDataSourcePropertie)) {
+                        String shardingDbName = myDataSourcePropertie.getShardingDbName();
                         //并且包含需要自动刷新的表
                         //并且包含需要自动刷新的表
                         if (myDataSourcePropertie.getTables().contains(logicTableName)) {
                         if (myDataSourcePropertie.getTables().contains(logicTableName)) {
                             //获取最近节点
                             //获取最近节点
                             List<DataNode> newDataNodes = getDataNodes(myDataSourcePropertie, dataSourceName, logicTableName);
                             List<DataNode> newDataNodes = getDataNodes(myDataSourcePropertie, dataSourceName, logicTableName);
-                            //刷新数据库jdbc连接信息
-                            dynamicRefreshDatasource(dataSourceName, tableRule, newDataNodes);
+                            dataNodeList.addAll(newDataNodes);
+
                         }
                         }
                     }
                     }
                 }
                 }
 
 
+
+            }
+
+            for (TableRule tableRule : tableRules) {
+                String logicTableName = tableRule.getLogicTable();
+                Map<String, List<DataNode>> dataListMap = data.get(logicTableName);
+                //刷新数据库jdbc连接信息
+                dynamicRefreshDatasourceNew(tableRule, dataListMap);
+
             }
             }
 
 
-        } catch (ShardingConfigurationException | NoSuchFieldException | IllegalAccessException | SQLException e) {
+//        } catch (ShardingConfigurationException | NoSuchFieldException | IllegalAccessException | SQLException e) {
+//            log.error(String.format("逻辑表:%s 动态分表配置错误!"));
+//        }
+        } catch (Exception e) {
             log.error(String.format("逻辑表:%s 动态分表配置错误!"));
             log.error(String.format("逻辑表:%s 动态分表配置错误!"));
         }
         }
     }
     }
 
 
+
     /**
     /**
-     * 获取数据节点
+     * 动态刷新数据源
      */
      */
-    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);
+    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);
         }
         }
-        // 扩展点
-        return 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);
+        System.out.println(tableRule);
     }
     }
 
 
     /**
     /**

+ 10 - 7
src/main/java/com/xin/shardingspherejdbcdemo/service/impl/UserServiceImpl.java

@@ -15,6 +15,7 @@ import com.xin.shardingspherejdbcdemo.utils.EntityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 
 
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
@@ -29,9 +30,15 @@ public class UserServiceImpl implements UserService {
     @Override
     @Override
     public PageVo list(int pageNum, int pageSize, String name, Integer age,Integer year) {
     public PageVo list(int pageNum, int pageSize, String name, Integer age,Integer year) {
         QueryWrapper queryWrapper = new QueryWrapper();
         QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.like("name", name);
-        queryWrapper.le("age", age);
-        queryWrapper.eq("year", year);
+        if(!StringUtils.isEmpty(name)){
+            queryWrapper.like("name", name);
+        }
+        if(!StringUtils.isEmpty(age)){
+            queryWrapper.le("age", age);
+        }
+        if(!StringUtils.isEmpty(year)){
+            queryWrapper.eq("year", year);
+        }
         int count = userMapper.selectCount(queryWrapper);
         int count = userMapper.selectCount(queryWrapper);
         queryWrapper.orderByDesc("create_time");
         queryWrapper.orderByDesc("create_time");
         queryWrapper.orderByAsc("age");
         queryWrapper.orderByAsc("age");
@@ -44,8 +51,6 @@ public class UserServiceImpl implements UserService {
 
 
     @Override
     @Override
     public User save(User user) {
     public User save(User user) {
-        SnowFlake snowFlake = new SnowFlake(2, 3);
-        user.setId(snowFlake.nextId());
         int year = EntityUtils.dateTostr(user.getCreateTime());
         int year = EntityUtils.dateTostr(user.getCreateTime());
         user.setYear(year);
         user.setYear(year);
         userMapper.insert(user);
         userMapper.insert(user);
@@ -77,8 +82,6 @@ public class UserServiceImpl implements UserService {
 
 
     @Override
     @Override
     public Object order(Order order) {
     public Object order(Order order) {
-        SnowFlake snowFlake = new SnowFlake(2, 3);
-        order.setId(snowFlake.nextId());
         int year = EntityUtils.dateTostr(order.getCreateTime());
         int year = EntityUtils.dateTostr(order.getCreateTime());
         order.setYear(year);
         order.setYear(year);
         orderMapper.insert(order);
         orderMapper.insert(order);

+ 2 - 2
src/main/resources/application-dev.yml

@@ -56,7 +56,7 @@ spring:
       tables:
       tables:
         #逻辑表名
         #逻辑表名
         t_user_:
         t_user_:
-          actual-data-nodes: sharding$->{0..1}.t_user_$->{2022..2023}
+          actual-data-nodes: sharding$->{0..1}.t_user_$->{2022}
 #          key-generator:
 #          key-generator:
 #            column: id
 #            column: id
 #            type: SNOWFLAKE
 #            type: SNOWFLAKE
@@ -69,7 +69,7 @@ spring:
               sharding-column: year
               sharding-column: year
               precise-algorithm-class-name: com.xin.shardingspherejdbcdemo.config.sharding.TableShardingAlgorithm
               precise-algorithm-class-name: com.xin.shardingspherejdbcdemo.config.sharding.TableShardingAlgorithm
         t_order_:
         t_order_:
-          actual-data-nodes: sharding$->{0..1}.t_order_$->{2022..2023}
+          actual-data-nodes: sharding$->{0..1}.t_order_$->{2022}
 #          key-generator:
 #          key-generator:
 #            column: id
 #            column: id
 #            type: SNOWFLAKE
 #            type: SNOWFLAKE