前言

ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。
Sharding-JDBC,定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

基础架构

SpringBoot+MyBatisPlus+sharding-jdbc+Druid

库表结构及分片策略

结构如上图,具体如下:

两个数据库:tp_1,tp_2;

四张表:tp_1.tp_member_0

   tp_1.tp_member_1

   tp_2.tp_member_0

   tp_2.tp_member_1

表结构具体如下:

OK,下面开始上代码:

1.依赖(不包含SpringBoot依赖):


<!-- mybatis-plus begin -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>RELEASE</version>
</dependency>

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>RELEASE</version>
</dependency>

<!-- for spring namespace -->
<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-namespace</artifactId>
    <version>RELEASE</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.25</version>
</dependency>

<!-- druid阿里巴巴数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.6</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

2.配置:

mybatis-plus.mapper-locations=classpath*:/mapper/*Mapper.xml

mybatis-plus.type-aliases-package=com.shardingsphere.demo.pojo

mybatis-plus.configuration.map-underscore-to-camel-case=true

mybatis-plus.configuration.cache-enabled=false

mybatis-plus.global-config.db-config.logic-delete-value=0

mybatis-plus.global-config.db-config.logic-not-delete-value=1

mybatis-plus.global-config.db-config.id-type=id_worker_str

mybatis-plus.global-config.db-config.field-strategy=not_empty

mybatis-plus.global-config.db-config.table-underline=true

sharding.jdbc.datasource.names=tp0,tp1


sharding.jdbc.datasource.tp0.type=com.alibaba.druid.pool.DruidDataSource

sharding.jdbc.datasource.tp0.driver-class-name=com.mysql.jdbc.Driver

sharding.jdbc.datasource.tp0.url=jdbc:mysql://localhost:3306/tp_1

sharding.jdbc.datasource.tp0.username=root

sharding.jdbc.datasource.tp0.password=rcms1234RCMS.


sharding.jdbc.datasource.tp1.type=com.alibaba.druid.pool.DruidDataSource

sharding.jdbc.datasource.tp1.driver-class-name=com.mysql.jdbc.Driver

sharding.jdbc.datasource.tp1.url=jdbc:mysql://localhost:3306/tp_2

sharding.jdbc.datasource.tp1.username=root

sharding.jdbc.datasource.tp1.password=rcms1234RCMS.


sharding.jdbc.config.sharding.props.sql.show=true

#根据id分表

sharding.jdbc.config.sharding.tables.tp_member.actual-data-nodes=tp$->{0..1}.tp_member_$->{0..1}

sharding.jdbc.config.sharding.tables.tp_member.table-strategy.inline.sharding-column=id

sharding.jdbc.config.sharding.tables.tp_member.table-strategy.inline.algorithm-expression=tp_member_$->{id % 2}

sharding.jdbc.config.sharding.tables.tp_member.key-generator-column-name=id

#主键生成器

#sharding.jdbc.config.sharding.tables.tp_member.key-generator-class-name=com.shardingsphere.demo.utils.KeyGenerator


#根据city_id分库

sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=city_id

sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=tp$->{city_id % 2}

3.注意点:

入口类上需要加上该注解:否则SpringBoot默认注入的Datasource会因为找不到配置而启动报错
@EnableAutoConfiguration(exclude = )
需要手动注入MyBatisPlus数据源,注意数据源的类型:

@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {

    MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();

    mybatisSqlSessionFactoryBean.setDataSource(dataSource);

    return mybatisSqlSessionFactoryBean.getObject();

}

4.验证效果:

(1).使用雪花算法生成id和city_id,往数据库插入100条数据,查看这100条数据的分布

(2).查询数据查看数据是否正确返回
(3).执行完步骤4,我们会发现这100条数据大致均匀的分布在四张表内,数据也能够正常返回

总结

sharding-jdbc实现分库分表提供了一套比较完备的逻辑,让我们能够像操作单库单表那样操作多个数据库。

但是这种分库分表带来的一些问题也是无法避免的。

分库分表带来的问题:

1.需要处理分布式事务

2.系统复杂性提升

3.复杂SQL能力大幅度下降