Configuración de la subtabla de la subbase de datos de ShardingSphere (SpringBoot+mybatis+mysql)

1. ¿Qué es ShardingSphere?

Posicionado como un marco ligero de Java, proporciona servicios adicionales en la capa JDBC de Java. Utiliza el cliente para conectarse directamente a la base de datos y proporciona servicios en forma de paquetes jar sin implementación ni dependencias adicionales.Puede entenderse como una versión mejorada del controlador JDBC y es totalmente compatible con JDBC y varios marcos ORM. Consta de tres productos independientes: Sharding-JDBC, Sharding-Proxy y Sharding-Sidecar (planeado). Todos proporcionan fragmentación de datos estandarizados, transacciones distribuidas y funciones de gobierno de bases de datos.

2. Escenarios de aplicación

Con el crecimiento de los negocios, un solo sistema de base de datos a menudo no puede cumplir con los escenarios de aplicación de datos masivos de Internet y encuentra cuellos de botella en términos de rendimiento, disponibilidad, operación y mantenimiento. Para resolver este problema, también se produce el middleware para la expansión horizontal y vertical de la base de datos (subbase de datos y subtabla) para satisfacer necesidades similares. El middleware común para la subbase de datos y la subtabla incluye MyCat, ShardingSphere y el servicio de base de datos distribuida DRDS de Alibaba. ShardingSphere es un conjunto de middleware de base de datos distribuida de código abierto. En la actualidad, una introducción detallada a la operación de configuración de la subbase de datos y la subtabla de ShardingSphere se basa en un ejemplo basado en springBoot+mybatis+mysql.

3. Proceso de implementación

1. Preparar el entorno de la base de datos

1. Primero instale dos bases de datos MySql

(sus puertos son 3306 y 3307 respectivamente), consulte aquí para conocer el método de creación .

2. Crear bases de datos en las dos bases de datos por separado

CREATE DATABASE shardingsphere;

3. Crea dos tablas en dos bases de datos

DROP TABLE IF EXISTS `t_user_0`;
CREATE TABLE `t_user_0`  (
  `user_id` bigint(32) NOT NULL COMMENT '主键',
  `id_number` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '身份证号码',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
  `age` int(4) NULL DEFAULT NULL COMMENT '年龄',
  `gender` int(2) NULL DEFAULT 1 COMMENT '性别:1-男;2-女',
  `birth_date` date NULL DEFAULT NULL COMMENT '出生日期',
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户表' ROW_FORMAT = Compact;

DROP TABLE IF EXISTS `t_user_1`;
CREATE TABLE `t_user_1`  (
  `user_id` bigint(32) NOT NULL COMMENT '主键',
  `id_number` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '身份证号码',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
  `age` int(4) NULL DEFAULT NULL COMMENT '年龄',
  `gender` int(2) NULL DEFAULT 1 COMMENT '性别:1-男;2-女',
  `birth_date` date NULL DEFAULT NULL COMMENT '出生日期',
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户表' ROW_FORMAT = Compact;

2. Implementación del código

1. Cree un sistema springBoot

(La herramienta IDE utilizada en este artículo es IntelliJ IDEA 2019.2 x64, búsquela y créela en Internet para el proceso específico), y el nombre del sistema es shardingsphere. Primero escriba el archivo pom.xml de maven. La versión utilizada por shardingSphere aquí es 3.1.0.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.teamo</groupId>
    <artifactId>shardingsphere</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>shardingsphere</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.shardingsphere</groupId>
            <artifactId>sharding-jdbc-core</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.5.13</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>5.1.32</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. Escriba el archivo de configuración archivo application.yml

Aquí se configuran principalmente dos fuentes de datos ds0 y ds1, que corresponden respectivamente a las dos bases de datos creadas al principio.

server:
  port: 8090
spring:
  datasource:
    type-aliases-package: com.teamo.shardingsphere.mapper
    mapper-locations: classpath:/mapper/*.xml
    ds0:
      url: jdbc:mysql://localhost:3306/shardingsphere?useUnicode=true&characterEncoding=utf-8&useSSL=true
      username: root
      password:
      driver-class-name: com.mysql.jdbc.Driver
      initialSize: 2                                #初始化大小
      maxWait: 6000                                 #获取连接时最大等待时间,单位毫秒。
      min-idle: 5                                   # 数据库连接池的最小维持连接数
      maxActive: 20                                  # 最大的连接数
      initial-size: 5                               # 初始化提供的连接数
      max-wait-millis: 200                       # 等待连接获取的最大超时时间
      type: com.alibaba.druid.pool.DruidDataSource
    ds1:
      url: jdbc:mysql://localhost:3307/shardingsphere?useUnicode=true&characterEncoding=utf-8&useSSL=true
      username: root
      password:
      driver-class-name: com.mysql.jdbc.Driver
      initialSize: 2                                #初始化大小
      maxWait: 6000                                 #获取连接时最大等待时间,单位毫秒。
      min-idle: 5                                   # 数据库连接池的最小维持连接数
      maxActive: 20                                  # 最大的连接数
      initial-size: 5                               # 初始化提供的连接数
      max-wait-millis: 200                          # 等待连接获取的最大超时时间
      type: com.alibaba.druid.pool.DruidDataSource
mybatis:
	configuration:
		map-underscore-to-camel-case: true
	type-aliases-package: com.teamo.shardingsphere.model
	mapper-locations: classpath:mapper/*.xml

3. Cree la clase de configuración de fuente de datos DataSourceConfig.java de shardingSphere

Debe prestarse especial atención al método userRuleConfig, que consiste en establecer las reglas de la subbase de datos y la subtabla para la tabla t_user.

3.1 La tabla t_user crea cuatro tablas en total, que son ds0_t_user0, ds0_t_user1, ds1_t_user0 y ds1_t_user1.
tableRuleConfig.setActualDataNodes(“ds0.t_user_0,ds0.t_user_1,ds1.t_user_0,ds1.t_user_1”);
3.2. La tabla t_user utiliza la clave principal user_id como clave de subbase de datos y clave de subtabla
//establecer t_user sub- reglas de base de datos
tableRuleConfig.setDatabaseShardingStrategyConfig(
new StandardShardingStrategyConfiguration("user_id", new DatabaseShardingAlgorithm()));
//Establecer t_user reglas de partición de tabla
tableRuleConfig.setTableShardingStrategyConfig(
new StandardShardingStrategyConfiguration("user_id", new IdCommonShardingAlgorithm()));
donde la clase DatabaseShardingAlgorithm es La clase de biblioteca, la clase IdCommonShardingAlgorithm se divide en clases de tabla, todas implementan la interfaz PreciseShardingAlgorithm e implementan la subbase de datos correspondiente y la lógica de la subtabla en el método de interfaz Para obtener detalles, consulte el contenido específico de estas dos clases.

package com.teamo.shardingsphere.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.teamo.shardingsphere.dbstrategy.DatabaseShardingAlgorithm;
import com.teamo.shardingsphere.dbstrategy.GenderTableShardingAlgorithm;
import com.teamo.shardingsphere.dbstrategy.IdCommonShardingAlgorithm;
import io.shardingsphere.api.config.rule.ShardingRuleConfiguration;
import io.shardingsphere.api.config.rule.TableRuleConfiguration;
import io.shardingsphere.api.config.strategy.InlineShardingStrategyConfiguration;
import io.shardingsphere.api.config.strategy.StandardShardingStrategyConfiguration;
import io.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import lombok.Data;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/***
 * @author teamo
 * @date 2022-03-18
 */
@Configuration
@Data
public class DataSourceConfig {
    
    
    @Value("${spring.datasource.type-aliases-package}")
    private String typeAliasesPackage;

    @Value("${spring.datasource.mapper-locations}")
    private String mapperLocation;

    @Value("${spring.datasource.ds0.url}")
    private String url0;
    @Value("${spring.datasource.ds0.username}")
    private String userName0;
    @Value("${spring.datasource.ds0.password}")
    private String password0;
    @Value("${spring.datasource.ds0.driver-class-name}")
    private String driverClassName0;
    @Value("${spring.datasource.ds0.type}")
    private String dsType0;

    @Value("${spring.datasource.ds1.url}")
    private String url1;
    @Value("${spring.datasource.ds1.username}")
    private String userName1;
    @Value("${spring.datasource.ds1.password}")
    private String password1;
    @Value("${spring.datasource.ds1.driver-class-name}")
    private String driverClassName1;
    @Value("${spring.datasource.ds1.type}")
    private String dsType1;

    /**
     * 获取数据源Map
     */
    private Map<String, DataSource> getDatasourceMap() {
    
    
        // 真实数据源map
        Map<String, DataSource> dataSourceMap = new HashMap<String, DataSource>(2);
        // 配置第一个数据源
        DruidDataSource dataSource0 = new DruidDataSource();
        dataSource0.setDriverClassName(driverClassName0);
        dataSource0.setUrl(url0);
        dataSource0.setUsername(userName0);
        dataSource0.setPassword(password0);
        dataSource0.setMinIdle(5);
        dataSource0.setMaxActive(20);
        dataSource0.setInitialSize(5);
        dataSource0.setMaxWait(6000);
        dataSourceMap.put("ds0", dataSource0);

        // 配置第二个数据源
        DruidDataSource dataSource1 = new DruidDataSource();
        dataSource1.setDriverClassName(driverClassName1);
        dataSource1.setUrl(url1);
        dataSource1.setUsername(userName1);
        dataSource1.setPassword(password1);
        dataSource1.setMinIdle(5);
        dataSource1.setMaxActive(20);
        dataSource1.setInitialSize(5);
        dataSource1.setMaxWait(6000);
        dataSourceMap.put("ds1", dataSource1);
        return dataSourceMap;
    }

    @Bean
    public Filter statFilter() {
    
    
        StatFilter filter = new StatFilter();
        filter.setSlowSqlMillis(5000);
        filter.setLogSlowSql(true);
        filter.setMergeSql(true);
        return filter;
    }

    @Bean
    public ServletRegistrationBean statViewServlet() {
    
    
        //创建servlet注册实体
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        //设置ip白名单
        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        //设置控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        servletRegistrationBean.addInitParameter("loginPassword", "123456");
        //是否可以重置数据
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    /****
     * sharding-jdbc-core(3.1.0)
     * @return
     * @throws SQLException
     */
    @Bean("dataSource")
    @Primary
    public DataSource dataSource() throws SQLException {
    
    
        // 配置真实数据源
        Map<String, DataSource> dataSourceMap = getDatasourceMap();
        // 配置分片规则
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        // 设置全局默认库
        //fshardingRuleConfig.setDefaultDataSourceName("ds0");
        shardingRuleConfig.getTableRuleConfigs().add(userRuleConfig());
        //设置默认数据源分片策略
        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new IdCommonShardingAlgorithm()));
        Properties p = new Properties();
        p.setProperty("sql.show",Boolean.TRUE.toString());
        // 获取数据源对象
        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new ConcurrentHashMap(), p);
        return dataSource;
    }

    /**
     * 需要手动配置事务管理器
     * @param dataSource
     * @return
     */
    @Bean
    public DataSourceTransactionManager transactitonManager(@Qualifier("dataSource") DataSource dataSource){
    
    
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean("sqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
    
    
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return bean.getObject();
    }

    @Bean("sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    private TableRuleConfiguration userRuleConfig() {
    
    
        TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration();
        tableRuleConfig.setLogicTable("t_user");
        tableRuleConfig.setActualDataNodes("ds0.t_user_0,ds0.t_user_1,ds1.t_user_0,ds1.t_user_1");
        tableRuleConfig.setKeyGeneratorColumnName("user_id");
        tableRuleConfig.setDatabaseShardingStrategyConfig(
                new StandardShardingStrategyConfiguration("user_id", new DatabaseShardingAlgorithm()));
        tableRuleConfig.setTableShardingStrategyConfig(
                new StandardShardingStrategyConfiguration("user_id", new IdCommonShardingAlgorithm()));
        return tableRuleConfig;
    }
}

4. Clase de regla de subbase de datos de tabla t_user DatabaseShardingAlgorithm

La lógica de la subbase de datos es el valor de la clave principal user_id y el valor de los 2 restantes para determinar la selección de la base de datos. Por ejemplo,
si actualmente se inserta un dato y el valor de la clave principal user_id es 3 , entonces (3%2==1) la base de datos selecciona db1

package com.teamo.shardingsphere.dbstrategy;

import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
import java.util.Collection;

/**
 * 数据源分片策略
 * @author teamo
 * @date 2022/3/18
 */
public class DatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    
    
    @Override
    public String doSharding(Collection<String> availableTargetNames,
                             PreciseShardingValue<Long> shardingValue) {
    
    
        long res = 0 ;
         for (String each : availableTargetNames) {
    
    
             res = shardingValue.getValue() ;
             res = res % 2;
             if (each.endsWith(res + "")) {
    
    
                 return each;
             }
         }
         throw new UnsupportedOperationException();
    }
}

5. Regla de subtabla de tabla t_user IdCommonShardingAlgorithm

La lógica de división de tablas es tomar el valor de la clave principal user_id de la tabla t_user, la longitud de user_id es len, tomar la suma entre 0 y len-1 dígitos, y usar el valor obtenido por el valor de suma %2 para determinar qué tabla elegir Ejemplo 1
: actualmente insertando un dato, el valor de user_id es 11, luego la longitud de user_id es 2, solo un dígito entre 0-1 es 1, luego 1% 2 = 1, por lo que el seleccionado la biblioteca es t_user1 Ejemplo 2: actualmente insertando una
pieza de datos, el valor de user_id es 131, luego la longitud de user_id es 3, el número entre 0-2 es 1 y 3, luego (1+3)%2=0, entonces la biblioteca seleccionada es t_user0

package com.teamo.shardingsphere.dbstrategy;

import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;

import java.util.Collection;

public class IdCommonShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    
    
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
    
    
        String target = availableTargetNames.stream().findFirst().get();
        for (String tableName : availableTargetNames) {
    
    
            if (tableName.endsWith(idToTableSuffix(shardingValue.getValue()))) {
    
    
                target = tableName;
            }
        }
        return target;
    }
    private String idToTableSuffix(Long id) {
    
    
        String idStr = String.valueOf(id);
        int total = 0;
        for(int i=0;i <idStr.length()-1; i++){
    
    
            Integer num = Integer.parseInt(idStr.substring(i,i+1));
            total+=num;
        }
        return String.valueOf(total % 2);
    }
}

6. Clase modelo

package com.teamo.shardingsphere.model;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
    
    
    private Long userId;
    private String idNumber;
    private String name;
    private Integer age;
    private Integer gender;
    private Date birthDate;
    private static final long serialVersionUID = 1L;
    public Long getUserId() {
    
    
        return userId;
    }
    public void setUserId(Long userId) {
    
    
        this.userId = userId;
    }
    public String getIdNumber() {
    
    
        return idNumber;
    }
    public void setIdNumber(String idNumber) {
    
    
        this.idNumber = idNumber == null ? null : idNumber.trim();
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name == null ? null : name.trim();
    }
    public Integer getAge() {
    
    
        return age;
    }
    public void setAge(Integer age) {
    
    
        this.age = age;
    }
    public Integer getGender() {
    
    
        return gender;
    }
    public void setGender(Integer gender) {
    
    
        this.gender = gender;
    }
    public Date getBirthDate() {
    
    
        return birthDate;
    }
    public void setBirthDate(Date birthDate) {
    
    
        this.birthDate = birthDate;
    }
}

7. Clase Dao

package com.teamo.shardingsphere.mapper;

import com.teamo.shardingsphere.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;

import java.util.List;

@Mapper
@Component
public interface UserMapper  {
    
    
    int deleteByPrimaryKey(Long userId);
    int insert(User record);
    int insertSelective(User record);
    User selectByPrimaryKey(Long userId);
    int updateByPrimaryKeySelective(User record);
    int updateByPrimaryKey(User record);
    List<User> selectAll(int start, int limit);
}

8. archivo de configuración del mapeador (archivo .xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.teamo.shardingsphere.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="com.teamo.shardingsphere.model.User">
    <id column="user_id" jdbcType="BIGINT" property="userId" />
    <result column="id_number" jdbcType="VARCHAR" property="idNumber" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="age" jdbcType="INTEGER" property="age" />
    <result column="gender" jdbcType="INTEGER" property="gender" />
    <result column="birth_date" jdbcType="DATE" property="birthDate" />
  </resultMap>
  <sql id="Base_Column_List">
    user_id, id_number, name, age, gender, birth_date
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from t_user
    where user_id = #{userId,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from t_user
    where user_id = #{userId,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.teamo.shardingsphere.model.User">
    insert into t_user (user_id, id_number, name,
      age, gender, birth_date
      )
    values (#{userId,jdbcType=BIGINT}, #{idNumber,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
      #{age,jdbcType=INTEGER}, #{gender,jdbcType=INTEGER}, #{birthDate,jdbcType=DATE}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.teamo.shardingsphere.model.User" useGeneratedKeys="true" keyProperty="userId">
    insert into t_user
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="userId != null">
        user_id,
      </if>
      <if test="idNumber != null">
        id_number,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="age != null">
        age,
      </if>
      <if test="gender != null">
        gender,
      </if>
      <if test="birthDate != null">
        birth_date,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="userId != null">
        #{userId,jdbcType=BIGINT},
      </if>
      <if test="idNumber != null">
        #{idNumber,jdbcType=VARCHAR},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        #{age,jdbcType=INTEGER},
      </if>
      <if test="gender != null">
        #{gender,jdbcType=INTEGER},
      </if>
      <if test="birthDate != null">
        #{birthDate,jdbcType=DATE},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.teamo.shardingsphere.model.User">
    update t_user
    <set>
      <if test="idNumber != null">
        id_number = #{idNumber,jdbcType=VARCHAR},
      </if>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        age = #{age,jdbcType=INTEGER},
      </if>
      <if test="gender != null">
        gender = #{gender,jdbcType=INTEGER},
      </if>
      <if test="birthDate != null">
        birth_date = #{birthDate,jdbcType=DATE},
      </if>
    </set>
    where user_id = #{userId,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.teamo.shardingsphere.model.User">
    update t_user
    set id_number = #{idNumber,jdbcType=VARCHAR},
      name = #{name,jdbcType=VARCHAR},
      age = #{age,jdbcType=INTEGER},
      gender = #{gender,jdbcType=INTEGER},
      birth_date = #{birthDate,jdbcType=DATE}
    where user_id = #{userId,jdbcType=BIGINT}
  </update>
  <select id="selectAll"  resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from t_user
    order by user_id
    limit #{start}, #{limit}
  </select>
</mapper>

9. Clase de servicio

Aquí hay un ejemplo de demostración, no hay forma de implementar la clase estrictamente de acuerdo con la interfaz

package com.teamo.shardingsphere.Service;

import com.teamo.shardingsphere.mapper.*;
import com.teamo.shardingsphere.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class BussinessService {
    
    
    @Autowired
    private UserMapper userMapper;
    @Transactional
    public void saveUser(User user) {
    
    
        userMapper.insertSelective(user);
    }

    public List<User> selectAllUser(int start, int limit ){
    
    
        return userMapper.selectAll(start, limit);
    }
}

10. Clase de controlador

La clase Controller ha escrito dos métodos, uno es el método de escritura de datos de la tabla t_user (usando for loop para escribir 40 registros y registros), y el otro es el método de consulta de la tabla t_user y la paginación, el propósito es detectar los datos escritos. en la tabla t_user y si operar de acuerdo con las reglas de la subbase de datos y la subtabla que establecemos al leer los datos.

package com.teamo.shardingsphere.controller;

import cn.hutool.core.date.DateUtil;
import com.teamo.shardingsphere.Service.BussinessService;
import com.teamo.shardingsphere.model.*;
import com.teamo.shardingsphere.util.SnowflakeKeyGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class BussinessController {
    
    
    @Autowired
    private BussinessService bussinessService;

    @GetMapping("/buss/create")
    public String create() {
    
    
        for (int i = 1; i <= 40; i++) {
    
    
            User user = new User();
            //user.setUserId(snowflakeKeyGenerator.nextId());
            user.setUserId(Long.parseLong((i)+""));
            user.setName("王小晖" + i);
            user.setGender(GenderEnum.MALE.getCode());
            user.setAge(20 + i);
            user.setBirthDate(DateUtil.parseDate("1989-08-16"));
            user.setIdNumber("4101231989691" + i);
            bussinessService.saveUser(user);
        }
        return "成功";
    }

    @GetMapping("/buss/allUser")
    public List<User> findAllUser(int start, int limit){
    
    
        return bussinessService.selectAllUser(start, limit);
    }
}

11. Clase de inicio de SpringBoot

package com.teamo.shardingsphere;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude={
    
    DataSourceAutoConfiguration.class})
public class ShardingsphereApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(ShardingsphereApplication.class, args);
    }
}

En este punto, todo el sistema de demostración está escrito

3. Ejecute la prueba

1. Inicie el sistema

Haga clic derecho en la clase de inicio para iniciar el sistema de demostración

inserte la descripción de la imagen aquí

2. Prueba de inserción de datos

Después de que el sistema se inicie correctamente, abra el navegador e ingrese http://localhost:9090/buss/create en la barra de direcciones.Cuando la página se muestra correctamente, indica que se ejecuta el método de inserción de datos en la tabla t_user exitosamente.
inserte la descripción de la imagen aquí
Luego inicie sesión en la base de datos y verifique la inserción de entrada en la biblioteca
ds0 de la tabla de la base de datos: Extraiga el tercer registro de las tablas t_user0 y t_user1 de la biblioteca ds0 para realizar la verificación lógica del
tercer registro de t_user0 user_id=6
El valor de user_id de la regla de la subbase de datos %2==0, por lo que la longitud del valor de ID_usuario de la regla de la subtabla de la subbase de datos a ds0
es 1, y no hay ningún número entre 0 y (1-1), que es 0 , por lo que la subtabla se divide en t_user0, por lo que
se insertará el registro con user_id=6 En la biblioteca ds0, en la tabla t_user0, la verificación es correcta

El id_usuario=14 del tercer registro de t_usuario1
es el valor de id_usuario en la regla de subbase de datos %2==0, por lo que
la longitud del valor de id_usuario de la regla de subtabla de subbase a ds0 es 2, y la valor entre [0 y (2-1)) es 1, presione La suma de las longitudes es 1, por lo que la tabla se divide en t_user1,
por lo que el registro con user_id=6 se insertará en la biblioteca ds0, la tabla t_user1 y la verificación es correcta
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
Biblioteca ds1
Biblioteca ds1: extraiga el quinto registro de las tablas t_user0 y t_user1 de la biblioteca ds0 para la verificación lógica de la subtabla de la subbase de datos User_id=9 del quinto
registro de t_user0
El valor de user_id en la regla de subbiblioteca %2 == 1, por lo que la sub-biblioteca La longitud del valor user_id de la
regla de la sub-tabla ds1 es 1, y no hay ningún número entre 0 y (1-1), que es 0, por lo que se asigna la sub-tabla a t_user0, por lo que el registro con
user_id=6 se insertará en la biblioteca ds1, la tabla t_user0 y la calibración Verificar que sea correcta

El id_usuario=19 del quinto registro de t_usuario1
es el valor de id_usuario de la regla de subbase de datos %2==1, por lo que la
longitud del valor de id_usuario de la regla de subtabla de subbase a ds1 es 2, y la valor entre [0 y (2-1)) es 1, presione La suma de las longitudes es 1, por lo que la tabla se divide en t_user1,
por lo que el registro con user_id=6 se insertará en la biblioteca ds1, la tabla t_user1 y la verificación es correcta
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3. Prueba de consulta de datos

Ingrese http://localhost:9090/buss/allUser?start=0&limit=5 en el navegador
inserte la descripción de la imagen aquípara ver el registro sql impreso en segundo plano. Después de que el sistema analiza las reglas de ShardingSphere, el sql realmente enviado a la base de datos es
inserte la descripción de la imagen aquí

Se puede ver que después de que ShardingSphere realiza operaciones de configuración de subbases de datos y subtablas, la fuente de datos de la consulta de tabla única del sistema se obtendrá de todas las tablas de bases de datos configuradas (en este caso, dos bases de datos y cuatro tablas).

Cuatro Resumen

Cuando planificamos el sistema al principio, si prevemos que el sistema puede tener riesgos de rendimiento causados ​​por un gran almacenamiento de datos, o durante el proceso de operación y mantenimiento, el sistema encuentra que el volumen de datos de cierta tabla en cierta empresa es demasiado grande para causar problemas de rendimiento. Considere la posibilidad de adoptar ShardingSphere. La clave para el uso eficiente de ShardingSphere es la determinación y el establecimiento de reglas de subtablas y bases de datos secundarias. La determinación de estas reglas debe determinarse de acuerdo con la lógica del negocio de consulta de la tabla. Solo un buen establecimiento de reglas puede hacer que muestre sus ventajas. La regla óptima para la clave de la subtabla de la subbase de datos es dividir los datos correspondientes en diferentes tablas según el negocio, como dividir según la unidad (siempre que el negocio se lleve a cabo en la misma unidad y haya menos unidades cruzadas). negocios), esto tendrá el efecto deseado.

Supongo que te gusta

Origin blog.csdn.net/teamo_m/article/details/123506140
Recomendado
Clasificación