shardingsphere从4.4.1升级至5.5.5注意事项

为方便讨论,假设有下面2张订单表:t_order_vip(用于存放VIP的订单),t_order_normal(用于存放普通用户的订单)  -- 注:为了演示自定义分片算法而设想的场景,大家不必太纠结其真实性。

分片规则:根据user_id,假设user_id为1,2,3的为VIP用户,其它id为普通用户

 

5.x与4.x版本有几个明显不同的地方:

一、 5.x不再支持传统的XML配置方式,而是采用YAML格式

 1 mode:
 2   type: Standalone
 3   repository:
 4     type: JDBC
 5 
 6 
 7 dataSources:
 8   ds_0:
 9     dataSourceClassName: com.zaxxer.hikari.HikariDataSource
10     driverClassName: com.mysql.jdbc.Driver
11     jdbcUrl: jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true
12     username: root
13     password: www.3power.CN
14     maxPoolSize: 10
15 
16 rules:
17   - !SHARDING
18     tables:
19       t_order:
20         actualDataNodes: ds_0.t_order_vip,ds_0.t_order_normal
21         tableStrategy:
22           standard:
23             shardingColumn: user_id
24             # 下面的t_order_inline名称可以随意命名,但要于下的shardingAlgorithms中的名称一致
25             shardingAlgorithmName: t_order_inline
26         keyGenerateStrategy:
27           column: order_id
28           keyGeneratorName: snowflake_generator
29 
30     shardingAlgorithms:
31       # 这里演示的是自定义分片算法
32       t_order_inline:
33         type: CLASS_BASED
34         props:
35           strategy: STANDARD
36           # 这里要填写完整的类名
37           algorithmClassName: shardingsphere.example.mybatis.custom.algorithm.CustomOrderIdAlgorithm
38 
39     keyGenerators:
40       snowflake_generator:
41         type: SNOWFLAKE
42 
43 props:
44   sql-show: true
View Code

对应4.x中的XML:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5        xmlns:context="http://www.springframework.org/schema/context"
 6        xmlns:tx="http://www.springframework.org/schema/tx"
 7        xmlns:sharding="http://shardingsphere.apache.org/schema/shardingsphere/sharding"
 8        xmlns:bean="http://www.springframework.org/schema/util"
 9        xsi:schemaLocation="http://www.springframework.org/schema/beans
10                         http://www.springframework.org/schema/beans/spring-beans.xsd 
11                         http://www.springframework.org/schema/tx 
12                         http://www.springframework.org/schema/tx/spring-tx.xsd
13                         http://www.springframework.org/schema/context 
14                         http://www.springframework.org/schema/context/spring-context.xsd
15                         http://shardingsphere.apache.org/schema/shardingsphere/sharding
16                         http://shardingsphere.apache.org/schema/shardingsphere/sharding/sharding.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
17     <context:component-scan base-package="shardingsphere.example.mybatis" />
18     
19     <bean id="ds_0" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
20         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
21         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ds0?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
22         <property name="username" value="root"/>
23         <property name="password" value="***"/>
24     </bean>
25 
26     <bean:properties id="properties">
27         <prop key="worker.id">123</prop>
28     </bean:properties>
29     
30     <sharding:key-generator id="orderKeyGenerator" type="SNOWFLAKE" column="order_id" props-ref="properties" />
31 
32     <!--自定义分片算法-->
33     <sharding:standard-strategy id="userIdStrategy" sharding-column="user_id"
34                                 precise-algorithm-ref="customOrderIdAlgorithm"/>
35     
36     <sharding:data-source id="shardingDataSource">
37         <sharding:sharding-rule data-source-names="ds_0" default-data-source-name="ds_0">
38             <sharding:table-rules>
39                 <sharding:table-rule logic-table="t_order"
40                                      actual-data-nodes="ds_0.t_order_vip,ds_0.t_order_normal"
41                                      table-strategy-ref="userIdStrategy"
42                                      key-generator-ref="orderKeyGenerator" />
43                 
44             </sharding:table-rules>
45         </sharding:sharding-rule>
46         <sharding:props>
47             <prop key="sql.show">true</prop>
48             <prop key="max.connections.size.per.query">10</prop>
49         </sharding:props>
50     </sharding:data-source>
51     
52     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
53         <property name="dataSource" ref="shardingDataSource" />
54     </bean>
55 
56     <tx:annotation-driven />
57     
58     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
59         <property name="dataSource" ref="shardingDataSource"/>
60         <property name="mapperLocations" value="classpath*:mappers/*.xml"/>
61     </bean>
62     
63     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
64         <property name="basePackage" value="shardingsphere.example.mybatis.repository"/>
65         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
66     </bean>
67 </beans>
View Code

 

二、自定义分片算法的写法不同

5.x中的写法,实现StandardShardingAlgorithm、ComplexKeysShardingAlgorithm、HintShardingAlgorithm中某1个即可

 1 package shardingsphere.example.mybatis.custom.algorithm;
 2 
 3 import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
 4 import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
 5 import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
 6 
 7 import java.util.Collection;
 8 import java.util.List;
 9 
10 public class CustomOrderIdAlgorithm implements StandardShardingAlgorithm<Integer> {
11 
12     @Override
13     public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
14         //演示自定义分片算法
15         //user_id是vip,在t_order_vip表中,否则在t_order_normal表中
16         String tableSuffix = "";
17         if (isVip(shardingValue.getValue())) {
18             tableSuffix = "_vip";
19         } else {
20             tableSuffix = "_normal";
21         }
22         for (String each : availableTargetNames) {
23             if (each.endsWith(tableSuffix)) {
24                 return each;
25             }
26         }
27         return "";
28     }
29 
30     boolean isVip(Integer userId) {
31         Integer value = userId % 10;
32         //user_id是1,2,3的视为vip(仅为演示)
33         List<Integer> vipUserIdList = List.of(1, 2, 3);
34         return vipUserIdList.contains(value);
35     }
36 
37     @Override
38     public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Integer> shardingValue) {
39         throw new RuntimeException("not supported");
40     }
41 }
View Code

4.x中的写法,实现PreciseShardingAlgorithm

 1 package shardingsphere.example.mybatis.custom.algorithm;
 2 
 3 import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
 4 import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
 5 import org.springframework.stereotype.Component;
 6 
 7 import java.util.Collection;
 8 import java.util.List;
 9 
10 @Component("customOrderIdAlgorithm")
11 public class CustomOrderIdAlgorithm implements PreciseShardingAlgorithm<Integer> {
12 
13     @Override
14     public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
15         //演示自定义分片算法
16         //user_id是vip,在t_order_vip表中,否则在t_order_normal表中
17         String tableSuffix = "";
18         if (isVip(shardingValue.getValue())) {
19             tableSuffix = "_vip";
20         } else {
21             tableSuffix = "_normal";
22         }
23         for (String each : availableTargetNames) {
24             if (each.endsWith(tableSuffix)) {
25                 return each;
26             }
27         }
28         return "";
29     }
30 
31     boolean isVip(Integer userId) {
32         Integer value = userId % 10;
33         //user_id是1,2,3的视为vip(仅为演示)
34         List<Integer> vipUserIdList = List.of(1, 2, 3);
35         return vipUserIdList.contains(value);
36     }
37 }
View Code

 

三、5.x 不再支持多个逻辑表(logic Table)对应同1个实际表(actual Table)

这个特性不再支持,我个人感觉是一种倒退。这个其实很有用,比如:如果只想查 VIP订单的数据(又不知道具体user_id),如果统一用逻辑表t_order来查询,会将所有分表全查一次,开销太大。在4.x中,可以这样处理(可参见:shading-jdbc 4.1.1 + tk.mybatis + pagehelper 1.3.x +spring boot 2.x 使用注意事项 - 菩提树下的杨过 - 博客园)

 1 <sharding:table-rule logic-table="t_order"
 2                      actual-data-nodes="ds_0.t_order_vip,ds_0.t_order_normal"
 3                      table-strategy-ref="userIdStrategy"
 4                      key-generator-ref="orderKeyGenerator" />
 5 
 6 <!--查order_vip逻辑表,将直接路由到t_order_vip表-->
 7 <sharding:table-rule logic-table="order_vip"
 8                      actual-data-nodes="ds_0.t_order_vip"
 9                      table-strategy-ref="userIdStrategy"
10                      key-generator-ref="orderKeyGenerator" />
11 
12 <!--查order_normal逻辑表,将直接路由到t_order_normal表-->
13 <sharding:table-rule logic-table="order_normal"
14                      actual-data-nodes="ds_0.t_order_normal"
15                      table-strategy-ref="userIdStrategy"
16                      key-generator-ref="orderKeyGenerator" />
17 </sharding:table-rules>
View Code

但5.x中如果这样配置:

 1 rules:
 2   - !SHARDING
 3     tables:
 4       t_order:
 5         actualDataNodes: ds_0.t_order_vip,ds_0.t_order_normal
 6         tableStrategy:
 7           standard:
 8             shardingColumn: user_id
 9             shardingAlgorithmName: t_order_inline
10         keyGenerateStrategy:
11           column: order_id
12           keyGeneratorName: snowflake_generator
13       
14       #order_vip映射到ds_0.t_order_vip(会报错)
15       order_vip:
16         actualDataNodes: ds_0.t_order_vip
17         tableStrategy:
18           standard:
19             shardingColumn: user_id
20             shardingAlgorithmName: t_order_inline
21         keyGenerateStrategy:
22           column: order_id
23           keyGeneratorName: snowflake_generator
View Code

运行时会报错:

Same actual data node cannot be configured in multiple logic tables in same database, logical table 'order_vip', actual data node 'ds_0.t_order_vip'.

github上也有人反馈这个:

Create sharding table rules with same data nodes will cause exception · Issue #33050 · apache/shardingsphere

5.5.2 Same actual data node cannot be configured in multiple logic tables in same database · Issue #34889 · apache/shardingsphere

 

示例代码: 

github: yjmyzz/shardingsphere-mybatis-spring-namespace-example_4.1.1_5.5.2: shardingsphere mybatis 示例(4.1.1&5.5.2版本)

gitee: shardingsphere-mybatis-spring-namespace-example_4.1.1_5.5.2: shardingsphere + mybatis + spring 示例(从官网修改而来),适用4.1.1与5.5.2

posted @ 2025-04-12 22:47  菩提树下的杨过  阅读(853)  评论(2)    收藏  举报