Sharding-JDBC分片策略、分布式事務、全局ID、讀寫分離


分片策略詳解 :

  https://shardingsphere.apache.org/document/current/cn/features/sharding/concept/sharding/

  Sharding-JDBC 中的分片策略有兩個維度:分庫(數據源分片)策略和分表策略。

  分庫策略表示數據路由到的物理目標數據源,分表分片策略表示數據被路由到的目標表。分表策略是依賴於分庫策略的,也就是說要先分庫再分表,當然也可以不分庫只分表。

  跟 Mycat 不一樣,Sharding-JDBC 沒有提供內置的分片算法,而是通過抽象成接口,讓開發者自行實現,這樣可以根據業務實際情況靈活地實現分片。

分片策略:

  包含分片鍵和分片算法,由於分片算法的獨立性,將其獨立抽離。真正可用於分片操作的是分片鍵 + 分片算法,也就是分片策略。分片算法是需要自定義的。可以用於分庫,也可以用於分

  Sharding-JDBC 提供了 5 種分片策略,這些策略全部繼承自 ShardingStrategy。

  1. 標准分片策略:對應 StandardShardingStrategy。提供對 SQL語句中的 =><>=<=IN 和 BETWEEN AND 的分片操作支持。 StandardShardingStrategy 只支持單分片鍵,提供 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 兩個分片算法。 PreciseShardingAlgorithm 是必選的,用於處理 = 和 IN 的分片。 RangeShardingAlgorithm 是可選的,用於處理 BETWEEN AND><>=<=分片,如果不配置 RangeShardingAlgorithm,SQL 中的 BETWEEN AND 將按照全庫路由處理。
  2. 復合分片策略:對應 ComplexShardingStrategy。復合分片策略。提供對 SQL 語句中的 =><>=<=IN 和 BETWEEN AND 的分片操作支持。 ComplexShardingStrategy 支持多分片鍵,由於多分片鍵之間的關系復雜,因此並未進行過多的封裝,而是直接將分片鍵值組合以及分片操作符透傳至分片算法,完全由應用開發者實現,提供最大的靈活度。
  3. 行表達式分片策略:對應 InlineShardingStrategy。使用 Groovy 的表達式,提供對 SQL 語句中的 = 和 IN 的分片操作支持,只支持單分片鍵。 對於簡單的分片算法,可以通過簡單的配置使用,從而避免繁瑣的 Java 代碼開發,如: t_user_$->{u_id % 8} 表示 t_user 表根據 u_id 模 8,而分成 8 張表,表名稱為 t_user_0 到 t_user_7。 
  4. Hint分片策略:對應 HintShardingStrategy。通過 Hint 指定分片值而非從 SQL 中提取分片值的方式進行分片的策略。
  5. 不分片策略:對應 NoneShardingStrategy。不分片的策略。

分片算法:

  通過分片算法將數據分片,支持通過 =>=<=><BETWEEN 和 IN 分片。 分片算法需要應用方開發者自行實現,可實現的靈活度非常高。目前提供4種分片算法。 由於分片算法和業務實現緊密相關,因此並未提供內置分片算法,而是通過分片策略將各種場景提煉出來,提供更高層級的抽象,並提供接口讓應用開發者自行實現分片算法。

  1. 精確分片算法:對應 PreciseShardingAlgorithm,用於處理使用單一鍵作為分片鍵的 = 與 IN 進行分片的場景。需要配合 StandardShardingStrategy 使用。
  2. 范圍分片算法:對應 RangeShardingAlgorithm,用於處理使用單一鍵作為分片鍵的 BETWEEN AND><>=<=進行分片的場景。需要配合 StandardShardingStrategy 使用。
  3. 復合分片算法:對應 ComplexKeysShardingAlgorithm,用於處理使用多鍵作為分片鍵進行分片的場景,包含多個分片鍵的邏輯較復雜,需要應用開發者自行處理其中的復雜度。需要配合 ComplexShardingStrategy 使用。
  4. Hint分片算法:對應 HintShardingAlgorithm,用於處理使用 Hint 行分片的場景。需要配合 HintShardingStrategy 使用。

  算法實現 :

  實現的話就是實現對應的算法接口,並且把實現類配置進去即可。下列就是這四種算法對應的接口。實現他們的  doSharding 方法即可。

public interface PreciseShardingAlgorithm<T extends Comparable<?>> extends ShardingAlgorithm {  String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<T> shardingValue); } public interface RangeShardingAlgorithm<T extends Comparable<?>> extends ShardingAlgorithm {  Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<T> shardingValue); } public interface ComplexKeysShardingAlgorithm extends ShardingAlgorithm { Collection<String> doSharding(Collection<String> availableTargetNames, Collection<ShardingValue> shardingValues); } public interface HintShardingAlgorithm extends ShardingAlgorithm { Collection<String> doSharding(Collection<String> availableTargetNames, ShardingValue shardingValue); }

  然后配置分庫分表策略的時候進行注入就行:

userTableRuleConfig.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", DBShardAlgo.class.getName())); userTableRuleConfig.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id",TblPreShardAlgo.class.getName(), TblRangeShardAlgo.class.getName()));

  其中 DBShardAlgo、TblPreShardAlgo、TblRangeShardAlgo都是自定義的策略類。如果 springboot下面 ,則按照如下配置:

sharding.jdbc.config.sharding.tables.user_info.databaseStrategy.standard.shardingColumn=user_id sharding.jdbc.config.sharding.tables.user_info.databaseStrategy.standard.preciseAlgorithmClassName=com.wuzz.demo.config.DBShardAlgo sharding.jdbc.config.sharding.tables.user_info.tableStrategy.standard.shardingColumn=user_id sharding.jdbc.config.sharding.tables.user_info.tableStrategy.standard.preciseAlgorithmClassName=com.wuzz.demo.config.TblPreShardAlgo sharding.jdbc.config.sharding.tables.user_info.tableStrategy.standard.rangeAlgorithmClassName=com.wuzz.demo.config.TblRangeShardAlgo

  在 5.0.0 版本開始基於 SPI 機制實現拓展,其中拓展接口為 StandardShardingAlgorithm ,實現類如下:

public class StandardModTableShardAlgorithm implements StandardShardingAlgorithm<Long> { private Properties props=new Properties(); /** * 用於處理=和IN的分片。 * @param collection 表示目標分片的集合 * @param preciseShardingValue 邏輯表相關信息 * @return * Mod */ @Override public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) { // collection :t_order_standard_0-4 表分片集合 //preciseShardingValue :真實表t_order_standard 分片鍵 order_id 及值
        for(String name:collection){ //根據order_id的值進行取模,得到一個目標值 //Order_id%4=3 //name.endsWith, "order_3".endWith("")
            if(name.endsWith(String.valueOf(preciseShardingValue.getValue()%4))){ return name; } } throw new UnsupportedOperationException(); } /** * 用於處理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND將按照全庫路由處理 * @param collection * @param rangeShardingValue * @return
     */ @Override public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) { Collection<String> result=new LinkedHashSet<>(collection.size()); for(Long i=rangeShardingValue.getValueRange().lowerEndpoint();i<=rangeShardingValue.getValueRange().upperEndpoint();i++){ for(String name:collection){ if(name.endsWith(String.valueOf(i%4))){ result.add(name); } } } return result; } /** * 初始化對象的時候調用的方法 */ @Override public void init() { } /** * 對應分片算法(sharding-algorithms)的類型 * @return
     */ @Override public String getType() { return "STANDARD_MOD"; } @Override public Properties getProps() { return this.props; } /** * 獲取分片相關屬性 * @param properties */ @Override public void setProps(Properties properties) { this.props=properties; } }

  基於SPI 在 classpath下 新建 META-INF/services 目錄 ,新建文件 org.apache.shardingsphere.sharding.spi.ShardingAlgorithm ,填入實現類全路徑:

com.wuzz.demo.StandardModTableShardAlgorithm

  啟用自定義分片策略:

server.port=8080 spring.shardingsphere.datasource.names=ds-0 spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSource spring.shardingsphere.datasource.common.driver-class-name=com.mysql.cj.jdbc.Driver spring.shardingsphere.datasource.ds-0.username=root spring.shardingsphere.datasource.ds-0.password=123456 spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://192.168.1.101:3306/study?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
#未分庫 spring.shardingsphere.rules.sharding.tables.t_order_standard.actual-data-nodes=ds-0.t_order_standard_$->{0..3} spring.shardingsphere.rules.sharding.tables.t_order_standard.table-strategy.standard.sharding-column=order_id spring.shardingsphere.rules.sharding.tables.t_order_standard.table-strategy.standard.sharding-algorithm-name=standard-mod # 分片鍵 spring.shardingsphere.rules.sharding.tables.t_order_standard.key-generate-strategy.column=order_id spring.shardingsphere.rules.sharding.tables.t_order_standard.key-generate-strategy.key-generator-name=snowflake # 自定義的名字,定義在類里面 spring.shardingsphere.rules.sharding.sharding-algorithms.standard-mod.type=STANDARD_MOD spring.shardingsphere.rules.sharding.sharding-algorithms.standard-mod.props.algorithm-class-name=com.wuzz.demo.StandardModTableShardAlgorithm spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123

  這樣就完成了自定義算法的實現。

讀寫分離:

  配置 Sharding-JDBC 之前需要配置 Mysql的主從復制。詳見:https://www.cnblogs.com/wuzhenzhao/p/10183600.html .

  配置完 Mysql的 主從復制以后。Sharding -JDBC 只需要進行以下配置:

server.port=8080
#spring.profiles.active=db-table
#spring.profiles.active=boundary-range
#spring.profiles.active=interval
#spring.profiles.active=volumn-range
#spring.profiles.active=custom-standard


spring.shardingsphere.props.sql-show=true
spring.shardingsphere.datasource.names="write-ds,read-ds"
spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.common.driver-class-name=com.mysql.cj.jdbc.Driver

spring.shardingsphere.datasource.write-ds.jdbc-url=jdbc:mysql://192.168.1.101:3306/study?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.write-ds.username=root
spring.shardingsphere.datasource.write-ds.password=123456

spring.shardingsphere.datasource.read-ds.jdbc-url=jdbc:mysql://192.168.1.103:3306/study?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.read-ds.username=root
spring.shardingsphere.datasource.read-ds.password=123456

# db0這個名字隨意定義,就是一個邏輯庫的名字
spring.shardingsphere.rules.replica-query.data-sources.db0.primary-data-source-name=write-ds
spring.shardingsphere.rules.replica-query.data-sources.db0.replica-data-source-names=read-ds
spring.shardingsphere.rules.replica-query.load-balancers.db0.type=ROUND_ROBIN
#無任何意義
spring.shardingsphere.rules.replica-query.load-balancers.db0.props.test=test

  然后通過 集成 Mybatis 進行數據庫的讀寫操作。會看到日志會打印當前操作哪個庫。

分布式事務支持:

  官網:https://shardingsphere.apache.org/document/current/cn/features/transaction/

  本地事務:

  在不開啟任何分布式事務管理器的前提下,讓每個數據節點各自管理自己的事務。 它們之間沒有協調以及通信的能力,也並不互相知曉其他數據節點事務的成功與否。 本地事務在性能方面無任何損耗,但在強一致性以及最終一致性方面則力不從心。

  兩階段提交:

  XA協議最早的分布式事務模型是由 X/Open 國際聯盟提出的 X/Open Distributed Transaction Processing (DTP) 模型,簡稱 XA 協議。

  基於XA協議實現的分布式事務對業務侵入很小。 它最大的優勢就是對使用方透明,用戶可以像使用本地事務一樣使用基於XA協議的分布式事務。 XA協議能夠嚴格保障事務 ACID 特性。

  嚴格保障事務 ACID 特性是一把雙刃劍。 事務執行在過程中需要將所需資源全部鎖定,它更加適用於執行時間確定的短事務。 對於長事務來說,整個事務進行期間對數據的獨占,將導致對熱點數據依賴的業務系統並發性能衰退明顯。 因此,在高並發的性能至上場景中,基於XA協議的分布式事務並不是最佳選擇。

  柔性事務:

  如果將實現了 ACID 的事務要素的事務稱為剛性事務的話,那么基於 BASE 事務要素的事務則稱為柔性事務。 BASE 是基本可用、柔性狀態和最終一致性這三個要素的縮寫。

  • 基本可用(Basically Available)保證分布式事務參與方不一定同時在線。

  • 柔性狀態(Soft state)則允許系統狀態更新有一定的延時,這個延時對客戶來說不一定能夠察覺。

  • 而最終一致性(Eventually consistent)通常是通過消息傳遞的方式保證系統的最終一致性。

  在 ACID 事務中對隔離性的要求很高,在事務執行過程中,必須將所有的資源鎖定。 柔性事務的理念則是通過業務邏輯將互斥鎖操作從資源層面上移至業務層面。通過放寬對強一致性要求,來換取系統吞吐量的提升。

  基於 ACID 的強一致性事務和基於 BASE 的最終一致性事務都不是銀彈,只有在最適合的場景中才能發揮它們的最大長處。 可通過下表詳細對比它們之間的區別,以幫助開發者進行技術選型。

  Sharding-JDBC下實現強一致分布式事務需要導入以下依賴:

<!--xa分布式事務-->
<dependency>
  <groupId>io.shardingsphere</groupId>
  <artifactId>sharding-transaction-2pc-xa</artifactId>
  <version>3.1.0</version>
</dependency>

<dependency>
  <groupId>io.shardingsphere</groupId>
  <artifactId>sharding-transaction-spring-boot-starter</artifactId>
  <version>3.1.0</version>
</dependency>

  默認是用 atomikos 實現的。在 Service 類上加上注解:

@ShardingTransactionType(TransactionType.XA) @Transactional(rollbackFor = Exception.class)

分布式全局 ID:

  傳統數據庫軟件開發中,主鍵自動生成技術是基本需求。而各個數據庫對於該需求也提供了相應的支持,比如 MySQL 的自增鍵,Oracle 的自增序列等。 數據分片后,不同數據節點生成全局唯一主鍵是非常棘手的問題。同一個邏輯表內的不同實際表之間的自增鍵由於無法互相感知而產生重復主鍵。 雖然可通過約束自增主鍵初始值和步長的方式避免碰撞,但需引入額外的運維規則,使解決方案缺乏完整性和可擴展性。

  目前有許多第三方解決方案可以完美解決這個問題,如 UUID 等依靠特定算法自生成不重復鍵,或者通過引入主鍵生成服務等。為了方便用戶使用、滿足不同用戶不同使用場景的需求, Apache ShardingSphere 不僅提供了內置的分布式主鍵生成器,例如 UUID、SNOWFLAKE,還抽離出分布式主鍵生成器的接口 KeyGenerator,方便用戶自行實現自定義的自增主鍵生成器。

  內置的主鍵生成器:

  • UUID:采用 UUID.randomUUID() 的方式產生分布式主鍵。
  • SNOWFLAKE:在分片規則配置模塊可配置每個表的主鍵生成策略,默認使用雪花算法(snowflake)生成 64bit 的長整型數據。雪花算法是由 Twitter 公布的分布式主鍵生成算法,它能夠保證不同進程主鍵的不重復性,以及相同進程主鍵的有序性。

  Java config 配置:

ShardingRuleConfiguration configuration = new ShardingRuleConfiguration();
//設置主鍵生成策略
// * UUID
// * 雪花算法
Properties idProperties = new Properties();
idProperties.setProperty("worker-id", "123");
configuration.getKeyGenerators().put("snowflake", new ShardingSphereAlgorithmConfiguration("SNOWFLAKE", idProperties));

  keyGeneratorColumnName:指定需要生成 ID 的列

  KeyGenerotorClass:指定生成器類,默認是 DefaultKeyGenerator.java,里面使用了雪花算法。

  Properties 配置:

# 分片鍵
spring.shardingsphere.rules.sharding.tables.t_order_standard.key-generate-strategy.column=order_id
spring.shardingsphere.rules.sharding.tables.t_order_standard.key-generate-strategy.key-generator-name=snowflake
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123

ShardingJDBC基於Zookeeper實現分布式治理:

  隨着數據規模的不斷膨脹,使用多節點集群的分布式方式逐漸成為趨勢。在這種情況下,如何高效、自 動化管理集群節點,實現不同節點的協同工作,配置一致性,狀態一致性,高可用性,可觀測性等,就 成為一個重要的挑戰。 集群管理的復雜性體現在,一方面我們需要把所有的節點,不管是底層數據庫節點,還是中間件或者業 務系統節點的狀態都統一管理起來,並且能實時探測到最新的配置變動情況,進一步為集群的調控和調 度提供依據。 另一方面,不同節點之間的統一協調,分庫分表策略以及規則同步,也需要我們能夠設計一套在分布式 情況下,進行全局事件通知機制以及獨占性操作的分布式協調鎖機制。在這方面,ShardingJDBC采用 了Zookeeper/Etcd來實現配置的同步,狀態變更通知,以及分布式鎖來控制排他操作。

  導入依賴:

<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>shardingsphere-governance-repository-zookeeper-curator</artifactId>
  <version>5.0.0-alpha</version>
</dependency>
<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>shardingsphere-jdbc-governance-spring-boot-starter</artifactId>
  <version>5.0.0-alpha</version>
  <exclusions>
                <exclusion>
                    <groupId>org.apache.shardingsphere</groupId>
                    <artifactId>shardingsphere-test</artifactId>
                </exclusion>
  </exclusions>
</dependency>

  如下配置:

spring.shardingsphere.governance.name=demo_spring_boot_ds_encrypt
# 本地配置是否覆蓋遠程配置,false表示不覆蓋
spring.shardingsphere.governance.overwrite=false

# Zookeeper/etcd
spring.shardingsphere.governance.registry-center.type=ZooKeeper
spring.shardingsphere.governance.registry-center.server-lists=192.168.1.101:2181
spring.shardingsphere.governance.registry-center.props.maxRetries=4
spring.shardingsphere.governance.registry-center.props.retryIntervalMilliseconds=6000

spring.shardingsphere.datasource.names=ds-0,ds-1
spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.common.driver-class-name=com.mysql.jdbc.Driver

spring.shardingsphere.datasource.ds-0.username=root
spring.shardingsphere.datasource.ds-0.password=123456
spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://192.168.1.101:3306/study?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8

spring.shardingsphere.datasource.ds-1.username=root
spring.shardingsphere.datasource.ds-1.password=123456
spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://192.168.1.101:3306/study2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8

spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=user_id
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=database-inline

spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds-$->{0..1}.t_order_$->{0..1}
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_id
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=t-order-inline

spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=order_id
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake

spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds-$->{user_id % 2}
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.algorithm-expression=t_order_$->{order_id % 2}
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-item-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-item-inline.props.algorithm-expression=t_order_item_$->{order_id % 2}

spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123

  啟動后可以在 Zookeeper 上面看到相關節點

  具體的請查看官方文檔。其實 zookeeper 作為配置中心,當我們修改 rule 節點下的配置信息,規則配置,可包括數據分片、讀寫分離等配置規則。 sharding-jdbc 會進行動態更新,當然,修改規則不能影響數據的分布,不然會出問題。官方也說明了不允許這樣操作。

  表結構配置,暫時不支持動態修改。

Sharding-JDBC 工作流程:

  內核剖析https://shardingsphere.apache.org/document/current/cn/features/sharding/principle/

  Sharding-JDBC 的原理總結起來很簡單:SQL 解析 => 執行器優化 => SQL 路由 => SQL 改寫 => SQL 執行 => 結果歸並。

  1. SQL 解析:分為詞法解析和語法解析。 先通過詞法解析器將 SQL 拆分為一個個不可再分的單詞。再使用語法解析器對 SQL 進行理解,並最終提煉出解析上下文。 解析上下文包括表、選擇項、排序項、分組項、聚合函數、分頁信息、查詢條件以及可能需要修改的占位符的標記。SQL 解析主要是詞法和語法的解析。目前常見的 SQL 解析器主要有 fdb,jsqlparser和 Druid。Sharding-JDBC1.4.x 之前的版本使用 Druid 作為 SQL 解析器。從 1.5.x 版本開始,Sharding-JDBC 采用完全自研的 SQL 解析引擎。
  2. 執行器優化:合並和優化分片條件,如 OR 等。
  3. SQL 路由:SQL 路由是根據分片規則配置以及解析上下文中的分片條件,將 SQL 定位至真正的數據源。它又分為直接路由、簡單路由和笛卡爾積路由。直接路由,使用 Hint 方式。Binding 表是指使用同樣的分片鍵和分片規則的一組表,也就是說任何情況下,Binding 表的分片結果應與主表一致。例如:order 表和 order_item 表,都根據 order_id分片,結果應是 order_1 與 order_item_1 成對出現。這樣的關聯查詢和單表查詢復雜度和性能相當。如果分片條件不是等於,而是 BETWEEN 或 IN,則路由結果不一定落入單庫(表),因此一條邏輯 SQL 最終可能拆分為多條 SQL 語句。笛卡爾積查詢最為復雜,因為無法根據 Binding 關系定位分片規則的一致性,所以非Binding 表的關聯查詢需要拆解為笛卡爾積組合執行。查詢性能較低,而且數據庫連接數較高,需謹慎使用。
  4. SQL 改寫:將邏輯表名稱改成真實表名稱,優化分頁查詢等
  5. SQL 執行:因為可能鏈接到多個真實數據源, Sharding -JDBC 將采用多線程並發執行 SQL。
  6. 結果歸並:例如數據的組裝、分頁、排序等等。

Sharding-JDBC 實現原理:

  JDBC 的四大核心對象?DataSource、Connection、Statement(PS)、ResulstSet。

  Sharding-JDBC 封裝了這四個核心類,在類名前面加上了 Sharding。

  如果說帶 Sharding 的類要替換 JDBC 的對象,那么一定要找到創建和調用他們的地方。ShardingDataSource 我們不說了,系統啟動的時候就創建好了。問 題 就 在 於 , 我 們 是 什 么 時 候 用 ShardingDataSource 獲 取 一 個ShardingConnection 的?我們以整合了 MyBatis 的項目為例。MyBatis 封裝了 JDBC 的核心對象,那么在MyBatis 操作 JDBC 四大對象的時候,就要替換成 Sharding-JDBC 的四大對象。 我 們 的 查 詢 方 法 最 終 會 走 到SimpleExecutor 的 doQuery()方法,這個是我們的前提知識,那我們直接在 doQuery()打斷點。doQuery()方法里面調用了 prepareStatement()創建連接。而返回的就是 一個 ShardingConnection ,所以后續都是采用 Sharding-JDBC自己的實現類去操作,從而替換了四大對象。

  更多內容請參考官網.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM