sharding分表后主键_Sharding-JDBC 使用入门和基本配置
一、什么是Sharding-JDBC
Sharding-JDBC定位為輕量級Java框架,在Java的JDBC層提供的額外服務(wù)。它使用客戶端直連數(shù)據(jù)庫,以jar包形式提供服務(wù),無需額外部署和依賴,可理解為增強版的JDBC驅(qū)動,完全兼容JDBC和各種ORM框架。
二、Sharding-JDBC能做什么
- 分庫 & 分表
- 讀寫分離
- 分布式主鍵
- 分布式事務(wù)
三、適用項目框架
Sharding-JDBC適用于:
- 任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
- 基于任何第三方的數(shù)據(jù)庫連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
- 支持任意實現(xiàn)JDBC規(guī)范的數(shù)據(jù)庫,目前支持MySQL,Oracle,SQLServer和PostgreSQL。
四、Maven依賴
<!-- sharding jdbc 開始--> <dependency><groupId>io.shardingsphere</groupId><artifactId>sharding-core</artifactId><version>${sharding.version}</version> </dependency> <dependency><groupId>io.shardingsphere</groupId><artifactId>sharding-jdbc-spring-namespace</artifactId><version>${sharding.version}</version> </dependency> <!—如果不配置分布式事務(wù)的話配置上邊兩個就夠了 --> <!--分布式事務(wù)引用依賴--> <dependency><groupId>io.shardingsphere</groupId><artifactId>sharding-transaction-2pc-xa</artifactId><version>${sharding.version}</version></dependency> <dependency><groupId>io.shardingsphere</groupId><artifactId>sharding-transaction-spring</artifactId><version>${sharding.version}</version> </dependency> <!-- sharding jdbc 結(jié)束--> <!--AspectJ AOP支持 --> <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${aspectjweaver.version}</version> </dependency>五、讀寫分離
5.1 數(shù)據(jù)源配置
先配置數(shù)據(jù)源
也可以配置讀寫分離
以下配置是ds0和ds1兩個數(shù)據(jù)庫的主和從一共四個數(shù)據(jù)源。
parentDs 是數(shù)據(jù)源公共的配置,抽出去以免寫重復(fù)代碼。
<!-- ds0的主--> <bean id="ds0_master" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" parent="parentDs"> <property name="driverClassName" value=""/><property name="url" value=""/> </bean> <!-- ds0的從--> <bean id="ds0_slave" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" parent="parentDs"><property name="driverClassName" value=""/><property name="url" value="${sharding.connection.url.0}"/> </bean> <!-- ds1的主--> <bean id="ds1_master" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" parent="parentDs"><property name="driverClassName" value=""/><property name="url" value="${sharding.connection.url.1}"/> </bean> <!-- ds1的從--> <bean id="ds1_slave" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" parent="parentDs"><property name="driverClassName" value=""/><property name="url" value="${sharding.connection.url.1}"/> </bean>5.2 讀寫分離配置
只配置主從不配置分庫分表的情況如下,如果要配置分庫分表則不需要下面這個配置。
master-data-source-name 是主數(shù)據(jù)源ID
slave-data-source-names 是從數(shù)據(jù)源ID
<master-slave:data-source id="masterSlaveDataSource" master-data-source-name="ds0_master, ds1_master" slave-data-source-names="ds0_slave, ds1_slave " ><master-slave:props><prop key="sql.show">${sql_show}</prop><prop key="executor.size">10</prop><prop key="foo">bar</prop></master-slave:props> </master-slave:data-source>5.3 讀寫分離和分庫分表一起配置
如果讀寫分離和分庫分表一起使用的話把主從路由配置到 shardingdata-source下就可以了。
sharding:master-slave-rule 的 id 就是配置出來的邏輯的數(shù)據(jù)源的名稱,如果多個從的話還可以通過配置strategy-ref來配置負(fù)載均衡。
master-data-source 配置的是主庫數(shù)據(jù)源ID 。
slave-data-source 配置的是從庫數(shù)據(jù)源ID,多個以逗號分開。
<!-- sharding數(shù)據(jù)源--> <sharding:data-source id="shardingDataSource"><!-- 讀寫分離的話要把所有的主從數(shù)據(jù)源都寫在這里--><sharding:sharding-ruledata-source-names="ds0_master,ds0_slave,ds1_master,ds1_slave "><!-- 讀寫分離的路由 一主一從配置 strategy-ref --><sharding:master-slave-rules><sharding:master-slave-rule id="ds0" master-data-source-name="ds0_master" slave-data-source-names="ds0_slave"/><sharding:master-slave-rule id="ds1" master-data-source-name="ds1_master" slave-data-source-names="ds1_slave"/></sharding:master-slave-rules><!-- 讀寫分離配置 結(jié)束--><sharding:table-rules><!— 這里是分庫分表路由的配置 --></sharding:table-rules><sharding:binding-table-rules><!—- 綁定表的配置 --> </sharding:binding-table-rules></sharding:sharding-rule> <sharding:props><!-- 顯示SQL --><prop key="sql.show">true</prop></sharding:props> </sharding:data-source>六、數(shù)據(jù)分片
6.1 分片支持
Sharding-JDBC提供了5種分片策略。由于分片算法和業(yè)務(wù)實現(xiàn)緊密相關(guān),因此Sharding-JDBC并未提供內(nèi)置分片算法,而是通過分片策略將各種場景提煉出來,提供更高層級的抽象,并提供接口讓應(yīng)用開發(fā)者自行實現(xiàn)分片算法。
StandardShardingStrategy
標(biāo)準(zhǔn)分片策略。提供對SQL語句中的=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持單分片鍵,提供PreciseShardingAlgorithm和RangeShardingAlgorithm兩個分片算法。PreciseShardingAlgorithm是必選的,用于處理=和IN的分片;RangeShardingAlgorithm是可選的,用于處理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND將按照全庫路由處理。
ComplexShardingStrategy
復(fù)合分片策略。提供對SQL語句中的=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片鍵,由于多分片鍵之間的關(guān)系復(fù)雜,因此Sharding-JDBC并未做過多的封裝,而是直接將分片鍵值組合以及分片操作符交于算法接口,完全由應(yīng)用開發(fā)者實現(xiàn),提供最大的靈活度。
InlineShardingStrategy
Inline表達式分片策略。使用Groovy的Inline表達式,提供對SQL語句中的=和IN的分片操作支持。InlineShardingStrategy只支持單分片鍵,對于簡單的分片算法,可以通過簡單的配置使用,從而避免繁瑣的Java代碼開發(fā),如: tuser${user_id % 8} 表示t_user表按照user_id按8取模分成8個表,表名稱為t_user_0到t_user_7。
HintShardingStrategy
通過Hint而非SQL解析的方式分片的策略。
NoneShardingStrategy
不分片的策略。
6.2 分片配置
標(biāo)準(zhǔn)分片配置
<!-- 標(biāo)準(zhǔn)分片策略。--> <bean id="demoUserStandardStrategy" class="shard.strategy.DemoUserStandardStrategy"/> <sharding:standard-strategy id="shardingDemoUserStandardStrategy"precise-algorithm-ref="demoUserStandardStrategy" sharding-column="id" range-algorithm-ref=""/>DemoUserStandardStrategy標(biāo)準(zhǔn)分片要實現(xiàn) PreciseShardingAlgorithm 接口,doSharding的兩個參數(shù)一個是所有數(shù)據(jù)源的cllection.另一個參數(shù)是執(zhí)行SQL時傳過來的分片的值。
/*** 根據(jù)ID取* 標(biāo)準(zhǔn)分片策略* 用于處理=和IN的分片* @author yulonggao* @date 2019/1/31 14:35*/ @Slf4j public class DemoUserStandardStrategy implements PreciseShardingAlgorithm<Long> {@Overridepublic String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {//這個里邊有異常會被處理掉,然后導(dǎo)致拿不到分片。但出異常一般是業(yè)務(wù)代碼寫錯了。//每條指定分片的操作都會調(diào)用此方法,如果是in 條件查詢的話每個值會調(diào)用一次此方法,如果是批量插入也是每一條都要調(diào)用一次進行分片log.info("DemoUserStandardStrategy_preciseShardingValue={}", preciseShardingValue);Long suffix = preciseShardingValue.getValue() % 4;log.info("suffix={}", suffix);final String targetDb = String.valueOf(Math.abs(suffix.intValue()));String shardingValue = collection.stream().filter(p -> p.endsWith(targetDb)).findFirst().get();log.info("preciseShardingValue={},shardingValue={}", preciseShardingValue, shardingValue);return shardingValue;}強制分片
<!-- 強制路由分片策略--> <bean id="demoUserHintStrategy" class="shard.strategy.DemoUserHintStrategy"/><!-- 強制路由例子使用--> <sharding:hint-strategy id="shardingDemoUserHintStrategy" algorithm-ref="demoUserHintStrategy"/>DemoUserHintStrategy 的Java 如下,強制分片要實現(xiàn)HintShardingAlgorithm接口。/*** DemoUserHint強制路由分片策略,其實可以共用,只是例子* @author yulonggao* @date 2019/1/31 14:35*/ @Slf4j public class DemoUserHintStrategy implements HintShardingAlgorithm {@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, ShardingValue shardingValue) {//availableTargetNames 這個參數(shù)是所有的dataSource的集合,shardingValue是HintManager傳過來的分片信息log.info("DemoUserHintStrategy_availableTargetNames={}", availableTargetNames);log.info("DemoUserHintStrategy_shardingValue={}", shardingValue);ListShardingValue listShardingValue = (ListShardingValue) shardingValue;Collection shardingValueList = listShardingValue.getValues();//因為調(diào)用的時候分片是直接傳的 DataSource的名稱,所以直接返回就可以了,如果傳其它值則要加業(yè)務(wù)邏輯進行分片篩選//返回結(jié)果只能是availableTargetNames 里邊所包含的return shardingValueList;}}生成分部式ID的配置,生成主鍵的類要實現(xiàn)KeyGenerator接口。
<!—主鍵生成 --> <bean id="keyId" class="shard.key.DefaultKeyGenerator"/>七、分布式事務(wù)
把下面這行代碼配置在spring里,shardingTransaction.xml 是jar包里邊帶的。
文件的源碼只有兩行配置:
<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="shardingDataSource"></property> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 事務(wù)支持--> <import resource="classpath:META-INF/shardingTransaction.xml"/>使用注解配置事務(wù)要同時使用ShardingTransactionType和Transactional兩個注解。
/*** 注意:@ShardingTransactionType需要同Spring的@Transactional配套使用,事務(wù)才會生效。* @param param* @return*/ @ShardingTransactionType(TransactionType.XA) @Transactional(rollbackFor = Exception.class) @Override public int addParam(DemoParam param) { log.info("addParam-param={}", param); return demoParamDao.addParam(param); }7.1 支持程度
完全支持非跨庫事務(wù),例如:僅分表或分庫但是路由的結(jié)果在單庫中。
完全支持因邏輯異常導(dǎo)致的跨庫事務(wù)。例如:同一事務(wù)中跨兩個庫更新,更新完畢后,拋出空指針,則兩個庫的內(nèi)容都能回滾。
支持?jǐn)?shù)據(jù)庫字段約束造成的回滾。
不支持因網(wǎng)絡(luò)、硬件異常導(dǎo)致的跨庫事務(wù)。例如:同一事務(wù)中跨兩個庫更新,更新完畢后、未提交之前,第一個庫死機,則只有第二個庫數(shù)據(jù)提交。
八、其他問題
關(guān)于order by 排序,如果排序的字段不在查詢結(jié)果中,生成的SQL也會被帶上,但結(jié)果不返回給你。
九、參考文檔
https://shardingsphere.apache.org/document/current/cn/manual/sharding-jdbc/usage/sharding/
作者:高玉瓏
來源:宜信技術(shù)學(xué)院
總結(jié)
以上是生活随笔為你收集整理的sharding分表后主键_Sharding-JDBC 使用入门和基本配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: layui下拉框往上显示跟往下显示_牛肉
- 下一篇: 魅族Flyme 10年了!重磅升级 8大