2022年Sharding-JDBC源码学习(一):梳理流程以及分析如何扩展服务

前言

  1. 怎样在Java的JDBC层提供额外的服务,源码是怎样实现的?
  2. 本篇文章首先梳理整个注册以及执行流程,发现Sharding-JDBC按照如下步骤提供服务
    2.1 Sharding-JDBC根据配置生成数据源ShardingSphereDataSource
    2.2 根据数据源获取连接ShardingSphereConnection
    2.3 通过连接将sql封装成ShardingSpherePreparedStatement
    2.4 委托ShardingSpherePreparedStatement执行update操作

环境搭建

  1. 下载shardingsphere的源码
  2. 切换到最新分支:5.1.0
  3. 编译打包(会生成相关的类)
  4. 参考issue修复方式对example的pom文件进行修改
    4.1 改动的点参考提交记录
  5. 安装mysql-server,创建两个库:demo_ds_0、demo_ds_1
  6. 启动example的sharding-spring-boot-mybatis-example模块的ShardingSpringBootMybatisExample
    6.1 结果展示:demo_ds_0、demo_ds_1两个库都新建了t_address表以及新增了10条记录
    在这里插入图片描述
    6.2 Sharding-JDBC是怎样实现的?很神奇

集成Sharding-JDBC

  1. 引入mybatis以及shardingsphere-jdbc的starter包
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
      </dependency>
      
      <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
      </dependency>
    
  2. 配置多数据源以及规则
    // 多数据源
    spring.shardingsphere.datasource.names=ds-0,ds-1
    
    spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    spring.shardingsphere.datasource.ds-0.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.ds-0.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.ds-0.username=root
    spring.shardingsphere.datasource.ds-0.password=
    
    spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    spring.shardingsphere.datasource.ds-1.type=com.zaxxer.hikari.HikariDataSource
    spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.ds-1.username=root
    spring.shardingsphere.datasource.ds-1.password=
    
    // 规则
    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.binding-tables[0]=t_order,t_order_item
    spring.shardingsphere.rules.sharding.broadcast-tables=t_address
    
    spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds-$->{0..1}.t_order
    
    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.tables.t_order_item.actual-data-nodes=ds-$->{0..1}.t_order_item
    
    spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.column=order_item_id
    spring.shardingsphere.rules.sharding.tables.t_order_item.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.key-generators.snowflake.type=SNOWFLAKE
    
  3. @MapperScan配置持久层的扫描路径

Sharding-JDBC怎样提供服务

  1. 通过调试发现,sharding-jdbc是通过mybatis提供的扩展点进行功能的增强
  2. 回顾一下mybatis的流程
    2.1 通过@MapperScan导入MapperScannerRegistrar,注册MapperScannerConfigurer
    2.2 MapperScannerConfigurer通过ClassPathMapperScanner扫描指定路径下的包,注册对应MapperFactoryBean的beanDefinition
    private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
    	// beanClassName:dao层接口名(org.apache.shardingsphere.example.core.mybatis.repository.MybatisAddressRepository)
    	definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
    	// beanClass为MapperFactoryBean
    	definition.setBeanClass(this.mapperFactoryBeanClass);
    	// 设置beanDefinition中按类型注入 --> 实例化MapperFactoryBean时会自动调用它的set方法
    	definition.setAutowireMode(2);
    }	
    
    2.3 MybatisAutoConfiguration配置SqlSessionFactory,注入到MapperFactoryBean中
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        if (this.sqlSessionTemplate == null || sqlSessionFactory != this.sqlSessionTemplate.getSqlSessionFactory()) {
            this.sqlSessionTemplate = this.createSqlSessionTemplate(sqlSessionFactory);
        }
    }
    
    2.4 MapperFactoryBean的getObject方法通过SqlSessionTemplate生成MapperProxy代理
  3. MapperProxy代理逻辑梳理
    在这里插入图片描述
    3.1 重点分析SimpleExecutor#doUpdate
    public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    	// dataSource -> connection --> PreparedStatement
    	stmt = this.prepareStatement(handler, ms.getStatementLog());
    	// 委托PreparedStatement执行update操作
    	var6 = handler.update(stmt);
    }
    
    3.2 Sharding-JDBC根据数据源配置生成ShardingSphereDataSource,通过数据源获取连接ShardingSphereConnection
    3.3 通过ShardingSphereConnection将sql封装成ShardingSpherePreparedStatement
    3.4 通过ShardingSpherePreparedStatement委托执行update操作

小结

   本篇文章主要介绍sql执行前注册流程以及代理执行流程,因为篇幅问题,对Sharding-JDBC具体怎样提供服务没有分析。下篇文章继续分析

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值