Sharding-JDBC定位為輕量級(jí)Java框架,在Java的JDBC層提供的額外服務(wù)。它使用客戶端直連數(shù)據(jù)庫(kù),以jar包形式提供服務(wù),無需額外部署和依賴,可理解為增強(qiáng)版的JDBC驅(qū)動(dòng),完全兼容JDBC和各種ORM框架。
創(chuàng)新互聯(lián)建站2013年開創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元三山做網(wǎng)站,已為上家服務(wù),為三山各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220
分庫(kù) & 分表
讀寫分離
分布式主鍵
Sharding-JDBC適用于:
任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
基于任何第三方的數(shù)據(jù)庫(kù)連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
io.shardingsphere
sharding-core
${sharding.version}
io.shardingsphere
sharding-jdbc-spring-namespace
${sharding.version}
io.shardingsphere
sharding-transaction-2pc-xa
${sharding.version}
io.shardingsphere
sharding-transaction-spring
${sharding.version}
org.aspectj
aspectjweaver
${aspectjweaver.version}
先配置數(shù)據(jù)源
也可以配置讀寫分離
以下配置是ds0
和ds1
兩個(gè)數(shù)據(jù)庫(kù)的主和從一共四個(gè)數(shù)據(jù)源。
parentDs
是數(shù)據(jù)源公共的配置,抽出去以免寫重復(fù)代碼。
只配置主從不配置分庫(kù)分表的情況如下,如果要配置分庫(kù)分表則不需要下面這個(gè)配置。
master-data-source-name
是主數(shù)據(jù)源ID
slave-data-source-names
是從數(shù)據(jù)源ID
${sql_show}
10
bar
如果讀寫分離和分庫(kù)分表一起使用的話把主從路由配置到 shardingdata-source下就可以了。
sharding:master-slave-rule
的 id 就是配置出來的邏輯的數(shù)據(jù)源的名稱,如果多個(gè)從的話還可以通過配置strategy-ref來配置負(fù)載均衡。
master-data-source
配置的是主庫(kù)數(shù)據(jù)源ID 。
slave-data-source
配置的是從庫(kù)數(shù)據(jù)源ID,多個(gè)以逗號(hào)分開。
true
Sharding-JDBC提供了5種分片策略。由于分片算法和業(yè)務(wù)實(shí)現(xiàn)緊密相關(guān),因此Sharding-JDBC并未提供內(nèi)置分片算法,而是通過分片策略將各種場(chǎng)景提煉出來,提供更高層級(jí)的抽象,并提供接口讓應(yīng)用開發(fā)者自行實(shí)現(xiàn)分片算法。
StandardShardingStrategy
標(biāo)準(zhǔn)分片策略。提供對(duì)SQL語句中的=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持單分片鍵,提供PreciseShardingAlgorithm和RangeShardingAlgorithm兩個(gè)分片算法。PreciseShardingAlgorithm是必選的,用于處理=和IN的分片;RangeShardingAlgorithm是可選的,用于處理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND將按照全庫(kù)路由處理。
ComplexShardingStrategy
復(fù)合分片策略。提供對(duì)SQL語句中的=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片鍵,由于多分片鍵之間的關(guān)系復(fù)雜,因此Sharding-JDBC并未做過多的封裝,而是直接將分片鍵值組合以及分片操作符交于算法接口,完全由應(yīng)用開發(fā)者實(shí)現(xiàn),提供最大的靈活度。
InlineShardingStrategy
Inline表達(dá)式分片策略。使用Groovy的Inline表達(dá)式,提供對(duì)SQL語句中的=和IN的分片操作支持。InlineShardingStrategy只支持單分片鍵,對(duì)于簡(jiǎn)單的分片算法,可以通過簡(jiǎn)單的配置使用,從而避免繁瑣的Java代碼開發(fā),如: tuser${user_id % 8} 表示t_user表按照user_id按8取模分成8個(gè)表,表名稱為t_user_0到t_user_7。
HintShardingStrategy
通過Hint而非SQL解析的方式分片的策略。
NoneShardingStrategy
不分片的策略。
標(biāo)準(zhǔn)分片配置
DemoUserStandardStrategy標(biāo)準(zhǔn)分片要實(shí)現(xiàn) PreciseShardingAlgorithm 接口,doSharding的兩個(gè)參數(shù)一個(gè)是所有數(shù)據(jù)源的cllection.另一個(gè)參數(shù)是執(zhí)行SQL時(shí)傳過來的分片的值。
/**
* 根據(jù)ID取
* 標(biāo)準(zhǔn)分片策略
* 用于處理=和IN的分片
* @author yulonggao
* @date 2019/1/31 14:35
*/
@Slf4j
public class DemoUserStandardStrategy implements PreciseShardingAlgorithm {
@Override
public String doSharding(Collection collection, PreciseShardingValue preciseShardingValue) {
//這個(gè)里邊有異常會(huì)被處理掉,然后導(dǎo)致拿不到分片。但出異常一般是業(yè)務(wù)代碼寫錯(cuò)了。
//每條指定分片的操作都會(huì)調(diào)用此方法,如果是in 條件查詢的話每個(gè)值會(huì)調(diào)用一次此方法,如果是批量插入也是每一條都要調(diào)用一次進(jìn)行分片
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;
}
強(qiáng)制分片
DemoUserHintStrategy 的Java 如下,強(qiáng)制分片要實(shí)現(xiàn)HintShardingAlgorithm接口。
/**
* DemoUserHint強(qiáng)制路由分片策略,其實(shí)可以共用,只是例子
* @author yulonggao
* @date 2019/1/31 14:35
*/
@Slf4j
public class DemoUserHintStrategy implements HintShardingAlgorithm {
@Override
public Collection doSharding(Collection availableTargetNames, ShardingValue shardingValue) {
//availableTargetNames 這個(gè)參數(shù)是所有的dataSource的集合,shardingValue是HintManager傳過來的分片信息
log.info("DemoUserHintStrategy_availableTargetNames={}", availableTargetNames);
log.info("DemoUserHintStrategy_shardingValue={}", shardingValue);
ListShardingValue listShardingValue = (ListShardingValue) shardingValue;
Collection shardingValueList = listShardingValue.getValues();
//因?yàn)檎{(diào)用的時(shí)候分片是直接傳的 DataSource的名稱,所以直接返回就可以了,如果傳其它值則要加業(yè)務(wù)邏輯進(jìn)行分片篩選
//返回結(jié)果只能是availableTargetNames 里邊所包含的
return shardingValueList;
}
}
生成分部式ID的配置,生成主鍵的類要實(shí)現(xiàn)KeyGenerator接口。
把下面這行代碼配置在spring里,shardingTransaction.xml 是jar包里邊帶的。
文件的源碼只有兩行配置:
使用注解配置事務(wù)要同時(shí)使用ShardingTransactionType和Transactional兩個(gè)注解。
/**
* 注意:@ShardingTransactionType需要同Spring的@Transactional配套使用,事務(wù)才會(huì)生效。
* @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);
}
完全支持非跨庫(kù)事務(wù),例如:僅分表或分庫(kù)但是路由的結(jié)果在單庫(kù)中。
完全支持因邏輯異常導(dǎo)致的跨庫(kù)事務(wù)。例如:同一事務(wù)中跨兩個(gè)庫(kù)更新,更新完畢后,拋出空指針,則兩個(gè)庫(kù)的內(nèi)容都能回滾。
支持?jǐn)?shù)據(jù)庫(kù)字段約束造成的回滾。
不支持因網(wǎng)絡(luò)、硬件異常導(dǎo)致的跨庫(kù)事務(wù)。例如:同一事務(wù)中跨兩個(gè)庫(kù)更新,更新完畢后、未提交之前,第一個(gè)庫(kù)死機(jī),則只有第二個(gè)庫(kù)數(shù)據(jù)提交。
關(guān)于order by 排序,如果排序的字段不在查詢結(jié)果中,生成的SQL也會(huì)被帶上,但結(jié)果不返回給你。
https://shardingsphere.apache.org/document/current/cn/manual/sharding-jdbc/usage/sharding/
作者:高玉瓏
來源:宜信技術(shù)學(xué)院