ShardingSphere-JDBC小伙伴之Mybatis-plus

前言

看到现在网上很多关于ShardingSphere-JDBC的example都是基于4.x或者3.x的,而且官方的example为了复用,结构比较复杂,对新手及其不友好,这里简单梳理一下,从搭建服务到示例,尽可能的方便新手快速入手,本文使用的是ShardingSphere-JDBC的5.0.0-alpha,具体的详细信息请参阅官方:https://shardingsphere.apache.org/

环境搭建

Build Dokcer Mysql

Docker version 19.03.8

//实例1docker run -p 3306:3306 --name mymysql0 -v $PWD/conf:/Users/duansg/app/docker_mysql/conf.d -v $PWD/logs:/Users/duansg/app/docker_mysql/logs -v $PWD/data:/Users/duansg/app/docker_mysql/data/ -e MYSQL_ROOT_PASSWORD=123456 -d mysql//实例2docker run -p 3307:3306 --name mymysql1 -v $PWD/conf:/Users/duansg/app/docker_mysql/conf.d -v $PWD/logs:/Users/duansg/app/docker_mysql/logs -v $PWD/data:/Users/duansg/app/docker_mysql/data/ -e MYSQL_ROOT_PASSWORD=123456 -d mysql

Create Database

Server version: 8.0.22

docker exec -it mysql0 mysql -u root -pmysql> create database demo00;Query OK, 1 row affected (0.01 sec)mysql> exit;---------------------------------------docker exec -it mysql1 mysql -u root -pmysql> create database demo01;Query OK, 1 row affected (0.01 sec)mysql> exit;

Create Table

order_info_0,order_info_1

mysql> CREATE TABLE demo00.order_info_0 (    ->     ID varchar(32) NOT NULL ,    ->    ORDER_CODE varchar(64),    ->  STATUS SMALLINT,    ->   PRIMARY KEY (ID)    -> ) ENGINE=InnoDB ;Query OK, 0 rows affected (0.05 sec)mysql> CREATE TABLE demo00.order_info_1 (    ->     ID varchar(32) NOT NULL ,    ->    ORDER_CODE varchar(64),    ->  STATUS SMALLINT,    ->   PRIMARY KEY (ID)     -> ) ENGINE=InnoDB ;Query OK, 0 rows affected (0.05 sec)--------mysql> CREATE TABLE demo01.order_info_0 (    ->     ID varchar(32) NOT NULL ,    ->    ORDER_CODE varchar(64),    ->  STATUS SMALLINT,    ->   PRIMARY KEY (ID)    -> ) ENGINE=InnoDB ;Query OK, 0 rows affected (0.05 sec)mysql> CREATE TABLE demo01.order_info_1 (    ->     ID varchar(32) NOT NULL ,    ->    ORDER_CODE varchar(64),    ->  STATUS SMALLINT,    ->   PRIMARY KEY (ID)     -> ) ENGINE=InnoDB ;Query OK, 0 rows affected (0.05 sec)

Catalog

Code Catalog

├─com.duansg.fuck.db│  ├─config│  │  │  ShardingDataSourceMybatisConfig│  │  └─ ShardingDataSourceMybatisPlusConfig│  ├─dao│  │  └─ OrderInfoMapper│  ├─entity│  │  └─ OrderInfo│  └─service│     │  OrderInfoService│     ├─ impl│     └─   OrderInfoServiceImpl└─ServerApplication

application.yml

Configuration file

server:  port: 8088#spring:#  datasource:#    driver-class-name: com.mysql.cj.jdbc.Driver#    url: jdbc:mysql://localhost:3306/demo00?serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true#    username: root#    password: 123456mybatis-plus:  #configuration:    #map-underscore-to-camel-case: true    #auto-mapping-behavior: full  mapper-locations: classpath*:/mapper/*Mapper.xml  type-aliases-package: com.duansg.fuck.db.entity  global-config:    # 逻辑删除配置    db-config:      # 删除前      logic-not-delete-value: 1      # 删除后      logic-delete-value: 0

sharding-databases.yml

Configuration file

# 配置真实数据源
dataSources:
  # 配置第 1 个数据源
  demo00: !!com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo00
    username: root
    password: 123456
  # 配置第 2 个数据源
  demo01: !!com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3307/demo01
    username: root
    password: 123456

rules:
  # 配置分片规则
  - !SHARDING
    tables:
      # 配置 order_info 表规则
      order_info:
        actualDataNodes: demo0${0..1}.order_info_${0..1}
        # 配置分表策略
        tableStrategy:
          standard:
            shardingColumn: id
            shardingAlgorithmName: table_inline
        # 主键生成策略    
        keyGenerateStrategy:
          column: id
          keyGeneratorName: snowflake
        # 配置分库策略
        databaseStrategy:
          standard:
            shardingColumn: order_code
            shardingAlgorithmName: database_inline
    # 配置分片算法
    shardingAlgorithms:
      database_inline:
        type: INLINE
        props:
          algorithm-expression: demo0${order_code.hashCode() % 2}
      table_inline:
        type: INLINE
        props:
          algorithm-expression: order_info_${id.hashCode() & Integer.MAX_VALUE % 2}

    keyGenerators:
      snowflake:
        type: SNOWFLAKE
        props:
          worker-id: 123
props:
  sql-show: true
 

Mybatis-plus数据源设置

Mybatis同理,其他代码不作展示,都是正常用法。


/**
 * ShardingDataSourceAutoConfig
 *
 * @author Duansg
 * @version 1.0
 * @date 2020/12/11 下午4:10
 */
@Configuration
public class ShardingDataSourceMybatisPlusConfig extends MybatisPlusAutoConfiguration {

    public ShardingDataSourceMybatisPlusConfig(MybatisPlusProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider, ObjectProvider<List<MybatisPlusPropertiesCustomizer>> mybatisPlusPropertiesCustomizerProvider, ApplicationContext applicationContext) {
        super(properties, interceptorsProvider, resourceLoader, databaseIdProvider, configurationCustomizersProvider, mybatisPlusPropertiesCustomizerProvider, applicationContext);
    }

    @Primary
    @Bean("dataSource")
    public DataSource getDataSource() throws SQLException, IOException {
        File file = new File(Thread.currentThread().getClass().getResource("/sharding-databases.yml").getFile());
        return YamlShardingSphereDataSourceFactory.createDataSource(file);
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource")DataSource dataSource) throws Exception {
        return super.sqlSessionFactory(getDataSource());
    }

    @Bean("sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory")SqlSessionFactory sqlSessionFactory) {
        return super.sqlSessionTemplate(sqlSessionFactory);
    }
}
 

测试

/**
 * Test
 *
 * @author duansg
 * @version 1.0
 * @date 2020/12/10 下午10:23
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ServerApplication.class)
public class Test {

    @Autowired
    private OrderInfoService orderInfoService;

    @org.junit.Test
    public void insert(){
        OrderInfo entity = new OrderInfo();
        Random random = new Random();
        entity.setOrderCode(String.valueOf(random.nextInt(10000)));
//        entity.setOrderCode(String.valueOf(1));
        entity.setStatus(0);
        boolean save = orderInfoService.save(entity);
        System.out.println(save);
    }

    @org.junit.Test
    public void del(){
        //在不知道是哪个库的前提下,会删除两个库里面的数据
        boolean b = orderInfoService.removeById("1337348308472991745");
        System.out.println(b);
    }

    @org.junit.Test
    public void select(){
        OrderInfo one = orderInfoService.getOne(new QueryWrapper<OrderInfo>().lambda()
                .eq(OrderInfo::getId, "1337348308472991745")
                .eq(OrderInfo::getOrderCode, "4082")
        );
        System.out.println(one);

    }
    @org.junit.Test
    public void update(){
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setStatus(1);
        boolean update = orderInfoService.update(orderInfo, new QueryWrapper<OrderInfo>().lambda()
                .eq(OrderInfo::getId, "1337349695730647042")
                .eq(OrderInfo::getOrderCode, "3475")
        );
        System.out.println(update);
    }
 

验证结果

mysql> select count(1) from demo00.order_info_0;+----------+| count(1) |+----------+|    11280 |+----------+1 row in set (0.05 sec)
mysql> select count(1) from demo00.order_info_1+----------+| count(1) |+----------+|    11284 |+----------+1 row in set (0.05 sec)
mysql> select count(1) from demo01.order_info_0;+----------+| count(1) |+----------+|    11339 |+----------+1 row in set (0.05 sec)
mysql> select count(1) from demo01.order_info_1+----------+| count(1) |+----------+|    11306 |+----------+1 row in set (0.05 sec)

避坑指南

Unable to load authentication plugin ‘caching_sha2_password‘

Server version: 8.0.22

/** *5.x版本是:default_authentication_plugin=mysql_native_password *8.x版本就是:default_authentication_plugin=caching_sha2_password *MySQL的版本升级就是为了更加安全,没有兼容旧的驱动而修改验证插件 *网上有使用运行命令将某个用户的验证模块改为旧版的模块 *不过我建议还是升级一下驱动版本吧 */<dependency>  <groupId>mysql</groupId>  <artifactId>mysql-connector-java</artifactId>  <version>8.0.22</version></dependency>

Sharding value must implements Comparable.

order_info_${id.hashCode() & Integer.MAX_VALUE % 2

/** * 原有的分表算法为order_info_${id.hashCode() % 2} * 通过debug源码找到如下问题点,犯了一个很傻X的问题,就是 * id.hashCode()的范围 */public final class InlineShardingAlgorithm implements StandardShardingAlgorithm<Comparable<?>> {
   
     //.....   public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Comparable<?>> shardingValue) {
   
           Closure<?> closure = this.createClosure();        closure.setProperty(shardingValue.getColumnName(), shardingValue.getValue());        return closure.call().toString();    }  //.....}

Invalid bound statement (not found)

mybatis

/** 
 * 问题是在使用insert等通用方法的时出现这个问题可以大致猜想一下,为什么编译通过了,执行却显示找不到方法? * 通过@Insert能否通过测试? * 见如上mp配置 */

猜你喜欢

转载自blog.csdn.net/weixin_37669199/article/details/111180241
今日推荐