04.數據庫分庫分表-shardingjdbc

摘要

定位爲輕量級Java框架,在Java的JDBC層提供的額外服務。 它使用客戶端直連數據庫,以jar包形式提供服務,無需額外部署和依賴,可理解爲增強版的JDBC驅動,完全兼容JDBC和各種ORM框架。

  • 適用於任何基於JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
  • 支持任何第三方的數據庫連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
  • 支持任意實現JDBC規範的數據庫。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92標準的數據庫。
    sharding-jdbc

應用

以springboot爲例,介紹使用當時以及效果。

集成

1. maven依賴

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-core-common</artifactId>
    <version>4.0.1</version>
</dependency>

2. 配置

#數據源名稱
spring.shardingsphere.datasource.names=ds0
#數據源配置
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.shardingsphere.datasource.ds0.url=jdbc:p6spy:mysql://localhost:3306/test_ym?useunicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
#t_user表分片
spring.shardingsphere.sharding.tables.t_user.actualDataNodes=ds0.t_user_$->{['0_0','0_1','9_0','9_1']}
#t_user表分表鍵
spring.shardingsphere.sharding.tables.t_user.tableStrategy.standard.shardingColumn=school_id
#t_user表分表策略
spring.shardingsphere.sharding.tables.t_user.tableStrategy.standard.preciseAlgorithmClassName=com.ym.config.CustomShardingAlgorithm

#t_class表分片
spring.shardingsphere.sharding.tables.t_class.actualDataNodes=ds0.t_class_$->{['0_0','0_1','9_0','9_1']}
#t_class表分表鍵
spring.shardingsphere.sharding.tables.t_class.tableStrategy.standard.shardingColumn=school_id
#t_class表分表策略
spring.shardingsphere.sharding.tables.t_class.tableStrategy.standard..preciseAlgorithmClassName=com.ym.config.CustomShardingAlgorithm
#綁定表
spring.shardingsphere.sharding.binding-tables[0]=t_user,t_class

3. 啓動
由於druid連接池啓動時會自動創建數據源DataSource。需要springboot啓動時停用druid默認創建數據源。

@EnableAutoConfiguration(exclude = DruidDataSourceAutoConfigure.class)

4.分表策略
上一篇已經說明,我們自己寫了一個服務(sharding-center),實現了根據邏輯表名+鍵值獲取具體物理表表名。此處分表策略只需要通過dubbo調用sharding-center中的ShardingRouterApi.getRouterTable()服務即可。
使用ShardingRouterTemplate 將dubbo服務封裝

@Component
public class ShardingRouterTemplate {
    @Reference(check = false)
    ShardingRouterApi shardingRouterApi;

    public String getRouterTable(String logicTableName, String shardingValue){
        Result result = shardingRouterApi.getRouterTable(logicTableName,shardingValue);
        if(ResultCode.SUCCESS==result.getCode()){
            return String.valueOf(result.getData());
        }
        throw new IllegalArgumentException();
    }
}

分表策略中直接調用ShardingRouterTemplate獲取物理表名:

public class CustomShardingAlgorithm implements PreciseShardingAlgorithm<String> {
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        ShardingRouterTemplate template=SpringBeanFactory.getBean(ShardingRouterTemplate.class);
        return template.getRouterTable(shardingValue.getLogicTableName(),shardingValue.getValue());

    }
}

ShardingRouterTemplate 代碼服務

效果

配置的分表規則如下:

id type logic_table_name physic_table_name rule deleted
1 normal t_user t_user_0_0 range:1-3 0
2 normal t_user t_user_0_1 single:4,5 0
4 default t_user t_user_9_* mod:2 0
5 normal t_class t_class_0_0 range:1-3 0
6 normal t_class t_class_0_1 single:4,5 0
8 default t_class t_class_9_* mod:2 0

規則爲:
school_id=1、2、3時對應物理表爲:t_user_0_0
school_id=4、5時對應物理表爲:t_user_0_0
school_id=其他時對應物理表爲:t_user_9_0或者t_user_9_1
使用p6spy插件直接打印最終執行的sql語句查看數據入庫情況。
1. 插入數據
插入school_id=1-9的數據

insert into t_class_0_0(id,class_name,school_id) values(164, '班級-1-1', '1')
insert into t_class_0_0(id,class_name,school_id) values(165, '班級-1-2', '1')
insert into t_class_0_0(id,class_name,school_id) values(166, '班級-2-1', '2')
insert into t_class_0_0(id,class_name,school_id) values(167, '班級-2-2', '2')
insert into t_class_0_0(id,class_name,school_id) values(168, '班級-3-1', '3')
insert into t_class_0_0(id,class_name,school_id) values(169, '班級-3-2', '3')
insert into t_class_0_1(id,class_name,school_id) values(170, '班級-4-1', '4')
insert into t_class_0_1(id,class_name,school_id) values(171, '班級-4-2', '4')
insert into t_class_0_1(id,class_name,school_id) values(172, '班級-5-1', '5')
insert into t_class_0_1(id,class_name,school_id) values(173, '班級-5-2', '5')
insert into t_class_9_0(id,class_name,school_id) values(174, '班級-6-1', '6')
insert into t_class_9_0(id,class_name,school_id) values(175, '班級-6-2', '6')
insert into t_class_9_1(id,class_name,school_id) values(176, '班級-7-1', '7')
insert into t_class_9_1(id,class_name,school_id) values(177, '班級-7-2', '7')
insert into t_class_9_0(id,class_name,school_id) values(178, '班級-8-1', '8')
insert into t_class_9_0(id,class_name,school_id) values(179, '班級-8-2', '8')
insert into t_class_9_1(id,class_name,school_id) values(180, '班級-9-1', '9')
insert into t_class_9_1(id,class_name,school_id) values(181, '班級-9-2', '9')

2. 查詢
查詢school_id =1、2、3、4的數據

select * from t_user_0_0 where school_id in  ('1','2','3','4')
select * from t_user_0_1 where school_id in  ('1','2','3','4')

3. 連表查詢
未配置表綁定時連表查詢會進行笛卡爾積查詢

select * from t_user_0_0 u inner join t_class_9_1 c on u.class_id=c.id where u.school_id = '1'
select * from t_user_0_0 u inner join t_class_9_0 c on u.class_id=c.id where u.school_id = '1'
select * from t_user_0_0 u inner join t_class_0_0 c on u.class_id=c.id where u.school_id = '1'
select * from t_user_0_0 u inner join t_class_0_1 c on u.class_id=c.id where u.school_id = '1'

配置了表綁定時直接綁定查詢

spring.shardingsphere.sharding.binding-tables[0]=t_user,t_class

select * from t_user_0_0 u inner join t_class_0_0 c on u.class_id=c.id where u.school_id = '1'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章