zoukankan      html  css  js  c++  java
  • Spring Boot整合Sharding-JDBC实现数据分表+读写分离io.shardingsphere(3)

       在本文中使用Spring Boot 2.4.1+MyBatis+Druid+Sharding-JDBC+MySQL进行读写分离的案件讲解。

    1、数据库准备

           1、192.168.8.162  test1主

           2、192.168.8.134  test1从

           3、192.168.8.176  test1从

    2、准备数据分表

    DROP TABLE IF EXISTS `t_user_0`;
    CREATE TABLE `t_user_0` (
      `id` int(10) NOT NULL,
      `name` varchar(50) NOT NULL,
      `sex` varchar(10) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    DROP TABLE IF EXISTS `t_user_1`;
    CREATE TABLE `t_user_1` (
      `id` int(10) NOT NULL,
      `name` varchar(50) NOT NULL,
      `sex` varchar(10) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    DROP TABLE IF EXISTS `t_user_2`;
    CREATE TABLE `t_user_2` (
      `id` int(10) NOT NULL,
      `name` varchar(50) NOT NULL,
      `sex` varchar(10) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    DROP TABLE IF EXISTS `t_user_3`;
    CREATE TABLE `t_user_3` (
      `id` int(10) NOT NULL,
      `name` varchar(50) NOT NULL,
      `sex` varchar(10) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    3、上代码

     1、pom.xml配置引入maven依赖

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--springboot整合mybatis的依赖 -->
            <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!-- 这里用的是sharding-jdbc-spring-boot-starter 需要注意的是,此时druid不能用spring-boot-starter版本的,需要用正常的包: -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    
            <dependency>
                <groupId>io.shardingsphere</groupId>
                <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
                <version>3.1.0.M1</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <scope>provided</scope>
            </dependency>

    2、在application.yml中配置引用数据源及分表信息

    mybatis.config-location: classpath:META-INF/mybatis-config.xml
    spring:
      profiles:
        active: sharding-tbl-ms
      main:
        allow-bean-definition-overriding: true
    
    sharding:
      jdbc:
             ### 数据库
        dataSource:
              ### 数据库的别名
          names: db-test0,db-test1,db-test2
           # 主库1 ,master数据库
          db-test0: 
             ###  数据源类别
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.8.162:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
            username: root
            password: root
            maxPoolSize: 20
             ### 从库1 ,slave数据库
          db-test1:
             ###  数据源类别
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.8.134:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
            username: root
            password: root
            maxPoolSize: 20
            ### 从库1 ,slave数据库
          db-test2:
             ###  数据源类别
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.8.176:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
            username: root
            password: root
            maxPoolSize: 20
        props:
          sql:
            show: true
        config:
          masterslave: # 配置读写分离
              # 配置从库选择策略,提供轮询与随机,这里选择用轮询//random 随机 //round-robin 轮询
            load-balance-algorithm-type: round-robin
            name: ds_0
          sharding:
            master-slave-rules:
              ds_0:
              ###配置的是主库的数据库名,本案例为db-test0,其中ds_0为分区名。
                master-data-source-name: db-test0
              ###配置的是从库的数据库名,本案例为db-test1、db-test2
                slave-data-source-names: db-test1,db-test2
            tables:
              ###需要分表的表名
              t_user:
              ###配置的分表信息,真实的数据库信息。ds_0.t_user_$->{03},表示读取ds_0数据源的user_0、user_1、user_2、user_3。
                actual-data-nodes: ds_0.t_user_$->{0..3}
                table-strategy:
                  standard:
              ###是配置数据分表的策略的类,这里是自定义的类MyPreciseShardingAlgorithm。
                    precise-algorithm-class-name: com.demo.shardingjdbc.MyPreciseShardingAlgorithm
              ###配置的数据分表的字段,是根据id来分的      
                    sharding-column: id

    3、配置分表分片规则(结合application.yml)

    package com.demo.shardingjdbc;
    
    
    
    import java.util.Collection;
    
    import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
    import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
    
    /**
     * 自定义实现 精准分片算法(PreciseShardingAlgorithm)接口
     * 数据表table的精准分片
     * @author hzy
     *
     */
    public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
    
        @Override
        public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
            for (String tableName : availableTargetNames) {
                if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
                    return tableName;
                }
            }
            throw new IllegalArgumentException();
        }
    
    }

    4、mybatis操作数据库配置

    User.java

    package com.demo.shardingjdbc.entity;
    
    import java.io.Serializable;
    
    import lombok.Data;
    @Data
    public class User implements Serializable {
    
        private static final long serialVersionUID = -1205226416664488559L;
        private Integer id;
        private String name;
        private String sex;
    
    }

    mapper层

    package com.demo.shardingjdbc.mapper;
    
    
    import org.apache.ibatis.annotations.Mapper;
    
    import com.demo.shardingjdbc.entity.User;
    
    import java.util.List;
    
    @Mapper
    public interface UserMapper {
    
        Integer addUser(User user);
    
        List<User> list();
    
    }

    mybatis配置文件mybatis-config.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.demo.shardingjdbc.entity"/>
        </typeAliases>
        <mappers>
            <mapper resource="META-INF/mappers/User.xml"/>
        </mappers>
    </configuration>

    user.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.demo.shardingjdbc.mapper.UserMapper">
        
        <resultMap id="baseResultMap" type="com.demo.shardingjdbc.entity.User">
            <result column="id" property="id" jdbcType="INTEGER" />
            <result column="name" property="name" jdbcType="VARCHAR" />
            <result column="sex" property="sex" jdbcType="VARCHAR" />
        </resultMap>
        
        <insert id="addUser" parameterType="com.demo.shardingjdbc.entity.User">
            INSERT INTO t_user (
              id, name, sex
            )
            VALUES (
            #{id,jdbcType=INTEGER},
            #{name,jdbcType=VARCHAR},
            #{sex,jdbcType=VARCHAR}
            )
        </insert>
       
        <select id="list" resultMap="baseResultMap">
            SELECT u.* FROM t_user u order by u.id
        </select>
    
    </mapper>

    5、service层

    package com.demo.shardingjdbc.service.impl;
    
    
    import com.demo.shardingjdbc.entity.User;
    import com.demo.shardingjdbc.mapper.UserMapper;
    import com.demo.shardingjdbc.service.UserService;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class UserServiceImpl  implements UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public Integer addUser(User user) {
    
            // 强制路由主库
            return userMapper.addUser(user);
        }
    
        @Override
        public List<User> list() {
    
            return userMapper.list();
        }
    }

    6、controller层

    package com.demo.shardingjdbc.controller;
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.demo.shardingjdbc.entity.User;
    import com.demo.shardingjdbc.service.UserService;
    
    import lombok.extern.slf4j.Slf4j;
    
    @RestController
    @Slf4j
    public class UserController {
    
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/users")
        public Object list() {
            return userService.list();
        }
    
        @GetMapping("/add")
        public Object add() {
            int num=0;
            for(int i=1;i<=150;i++) {
                User user = new User();
                user.setId(i);
                user.setName("hzy"+(i));
                String sex=(i%2==0)? "":"";
                user.setSex(sex);
                    
               int resutl=   userService.addUser(user);
                log.info("insert:"+user.toString()+" result:"+resutl);
                num=num+resutl;
            }
            return num;
        }
    }

     完成。在浏览器上执行localhost:8080/add,然后去数据库中查询,可以看到t_user_0、t_user_1、t_user_2、t_user_3分别插入了数据。
    然后访问localhost:8080/users,可以查询数据库中四个表中的所有数据。可见Sharding-JDBC在插入数据的时候,根据数据分表策略,将数据存储在不同的表中,查询的时候将数据库从多个表中查询并聚合.

  • 相关阅读:
    poj 3662 Telephone Lines
    费马小定理证明
    CodeForces 1058 F Putting Boxes Together 树状数组,带权中位数
    共价大爷游长沙 lct 维护子树信息
    牛客暑假多校 F RIKKA with Line Graph
    牛客暑假多校 H Prefix sum
    HDU-6437 Videos
    模板汇总——AC自动机
    模板汇总——逆元
    模板汇总——LCT
  • 原文地址:https://www.cnblogs.com/h-z-y/p/14283281.html
Copyright © 2011-2022 走看看