shardingJdbc专题系列(五)之Inline策略 java config 实现方式

  前面几篇文章我们都是通过yml配置文件的方式,简单实现了 inline模式下的分库分表。 通过yml的方式,我们需要在配置文件中配置数据源和分库分表的策略表达式。那么如果我不想在配置文件中写如此冗长的配置,能否采用java config 的方式实现呢。肯定是可以的。

  本篇文章我们就来介绍通过java config的方式来重新实现inline模式下的分库分表。本次代码案例我们在git脚手架里的 sharding-inline-java 的module下进行。(git地址参看第一篇文章)

  首先还是先依赖 sharding-biz, 主要是配置文件。

  首先在config包下创建 MybatisPlusConfig 配置类,内容如下;  (注意:有一个ConditionOnBean注解,用来限制类的加载顺序,防止出错)

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "cn.cestc.biz.mapper")
@ConditionalOnBean(value= DataSource.class)
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setLimit(-1);
        return paginationInterceptor;
    }
}

第二步,添加一个 shardingJdbc的配置类,用来替换原来的yml

import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.spring.boot.util.DataSourceUtil;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;

/**
 * @className: ShardingDataSourceConfiguration
 * @description:
 * @author: sh.Liu
 * @date: 2020-11-03 19:23
 */
@Configuration
@MapperScan(basePackages = "cn.cestc.biz.mapper")
public class ShardingDataSourceConfiguration {

    @Bean("shardingDataSource")
    public DataSource getShardingDataSource() throws SQLException, ReflectiveOperationException {
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        // 广播表
        List<String> broadcastTables = new LinkedList<>();
        broadcastTables.add("t_user");
        broadcastTables.add("t_address");
        shardingRuleConfig.setBroadcastTables(broadcastTables);

        // 默认策略
        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "ds0"));
        shardingRuleConfig.setDefaultTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "t_order_${user_id % 4 + 1}"));
        // 获取user表的分片规则配置
        TableRuleConfiguration userInfoTableRuleConfiguration = getUserInfoTableRuleConfiguration();

        shardingRuleConfig.getTableRuleConfigs().add(userInfoTableRuleConfiguration);
        Properties props = new Properties();
        props.put("sql.show", "true");
        return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, props);
    }

    /**
     * 配置真实数据源
     * @return 数据源map
     */
    private Map<String, DataSource> createDataSourceMap() throws ReflectiveOperationException {
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        Map<String, Object> dataSourceProperties = new HashMap<>();
        dataSourceProperties.put("DriverClassName", "com.mysql.jdbc.Driver");
        dataSourceProperties.put("jdbcUrl", "jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8");
        dataSourceProperties.put("username", "root");
        dataSourceProperties.put("password", "root");

        DataSource dataSource1 = DataSourceUtil.getDataSource("com.zaxxer.hikari.HikariDataSource", dataSourceProperties);

        Map<String, Object> dataSourceProperties2 = new HashMap<>();
        dataSourceProperties2.put("DriverClassName", "com.mysql.jdbc.Driver");
        dataSourceProperties2.put("jdbcUrl", "jdbc:mysql://localhost:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8");
        dataSourceProperties2.put("username", "root");
        dataSourceProperties2.put("password", "root");

        DataSource dataSource2 = DataSourceUtil.getDataSource("com.zaxxer.hikari.HikariDataSource", dataSourceProperties2);

        dataSourceMap.put("ds0",dataSource1);
        dataSourceMap.put("ds1",dataSource2);
        return dataSourceMap;
    }

    /**
     * 配置user表的分片规则
     *
     * @return ser表的分片规则配置对象
     */
    private TableRuleConfiguration getUserInfoTableRuleConfiguration() {
        // 为user表配置数据节点
        TableRuleConfiguration ruleConfiguration = new TableRuleConfiguration("t_order", "ds0.t_order_$->{1..4}");
        // 设置分片键
        String shardingKey = "user_id";
        // 为user表配置分库分片策略及分片算法
        ruleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration(shardingKey, "ds$->{user_id % 2}"));
        // 为user表配置分表分片策略及分片算法
        ruleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration(shardingKey, "t_order_${user_id % 4 + 1}"));
        ruleConfiguration.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "order_id"));
        return ruleConfiguration;
    }
}

这个类中,配置了数据源的集合,同时在getUserInfoTableRuleConfiguration 方法中配置了order表的分库分表策略,和之前yml文件中的配置都是对应的,如果有多个表,添加多个方法,在getShardingDataSource 方法中添加(add) 多个策略即可。

最关键的是启动类,需要排除一个类   @SpringBootApplication(exclude = {SpringBootConfiguration.class}), 注意的是 SpringBootConfiguration要选择的是 shardingjdbc包下面的这个类:代码如下

import org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @className: ShardingInlineJavaApplication
 * @description:
 * @author: sh.Liu
 * @date: 2020-11-15 10:57
 */
@SpringBootApplication(exclude = {SpringBootConfiguration.class})
public class ShardingInlineJavaApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShardingInlineJavaApplication.class, args);
    }
}

 

好了,万事具备,接下来写一个测试的Controller, 测试一下分库分表的策略是否生效即可。

关于inline模式的分库分表到这里就告一段落了,在这一部分中,我们详细介绍了inline模式如何分库,如何分表,以及如何使用java config 实现。 下一部分我们重点研究下一种策略, standard标准策略的分库分表。

上一篇:【ShardingSphere技术专题】「ShardingJDBC」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)


下一篇:[51NOD1090] 3个数和为0(水题,二分)