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

    1、数据库准备

           1、192.168.8.162  test1主

           2、192.168.8.134  test1从

           3、192.168.8.176  test1从

           4、192.168.8.162  test2主

           5、192.168.8.134  test2从

           6、192.168.8.176  test2从

    2、准备分库分表

    USE `test1`;
    
    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;
    
    
    USE `test2`;
    
    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: ds-master-0,ds-master-1,ds-master-0-slave-0,ds-master-0-slave-1,ds-master-1-slave-0,ds-master-1-slave-1
           # 主库1 ,master数据库
          ds-master-0: 
             ###  数据源类别
            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从库1 ,slave数据库
          ds-master-0-slave-0:
             ###  数据源类别
            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从库1 ,slave数据库
          ds-master-0-slave-1:
             ###  数据源类别
            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
            # 主库2 ,master数据库
          ds-master-1: 
             ###  数据源类别
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.8.162:3306/test2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
            username: root
            password: root
            maxPoolSize: 20
             ### 主库2从库1 ,slave数据库
          ds-master-1-slave-0:
             ###  数据源类别
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.8.134:3306/test2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
            username: root
            password: root
            maxPoolSize: 20
            ### 主库2从库2 ,slave数据库
          ds-master-1-slave-1:
             ###  数据源类别
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.8.176:3306/test2?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: datasource
          sharding:
            master-slave-rules:
              ds_0:
              ###配置的是主库的数据库名,本案例为ds-master-0,其中ds_0为分区名。
                master-data-source-name: ds-master-0
              ###配置的是从库的数据库名,本案例为ds-master-0-slave-0,ds-master-0-slave-1
                slave-data-source-names: ds-master-0-slave-0,ds-master-0-slave-1
              ds_1:
              ###配置的是主库的数据库名,本案例为ds-master-1,其中ds_1为分区名。
                master-data-source-name: ds-master-1
              ###配置的是从库的数据库名,本案例为ds-master-1-slave-0,ds-master-1-slave-1
                slave-data-source-names: ds-master-1-slave-0,ds-master-1-slave-1
            tables:
              ###需要分表的表名
              t_user:
              ###配置的分表信息,真实的数据库信息。ds_0.t_user_$->{03},表示读取ds_0数据源的user_0、user_1、user_2、user_3。
                actual-data-nodes: ds_$->{0..1}.t_user_$->{0..3}
                database-strategy:
                  standard:
                ###是配置数据分库的策略的类,这里是自定义的类MyDBPreciseShardingAlgorithm
                    precise-algorithm-class-name: com.demo.shardingjdbc.MyDBPreciseShardingAlgorithm
               ###配置的数据分表的字段,是根据id来分的
                    sharding-column: id
                table-strategy:
                  standard:
              ###是配置数据分表的策略的类,这里是自定义的类MyTablePreciseShardingAlgorithm
                    precise-algorithm-class-name: com.demo.shardingjdbc.MyTablePreciseShardingAlgorithm
              ###配置的数据分表的字段,是根据id来分的      
                    sharding-column: id

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

           分库规则(结合pplication.yml中database-strategy)

    package com.demo.shardingjdbc;
    
    
    import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
    import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
    
    import java.util.Collection;
    
    /**
     * 自定义分片算法
     * 
     * @author hzy
     *
     */
    public class MyDBPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
    
        @Override
        public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
            for (String tableName : availableTargetNames) {
                if (tableName.endsWith(shardingValue.getValue() % 2 + "")) {
                    return tableName;
                }
            }
            throw new IllegalArgumentException();
        }
    
    }

         分表规则(结合pplication.yml中table-strategy)

      

    package com.demo.shardingjdbc;
    
    
    import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
    import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
    
    import java.util.Collection;
    
    /**
     * 自定义分片算法
     * 
     * @author hzy
     *
     */
    public class MyTablePreciseShardingAlgorithm 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<=300;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,然后去数据库中查询,可以看到test1.t_user_0、test1.t_user_2、test2.t_user_1、test2.t_user_3分别插入了数据。

       然后访问localhost:8080/users,可以查询数据库中四个表中的所有数据。可见Sharding-JDBC在插入数据的时候,根据数据分库分表策略,将数据存储在不同库不同表中,查询时将数据库从多个表中查询并聚合。

  • 相关阅读:
    计算机精英协会考核题 —— 第三题:斐波那契数
    pandas向表格中循环写入数据
    fiddler导出请求返回的响应数据
    notepad++下载及安装
    UVA 1647 Computer Transformation(计算机变换)(找规律)
    UVA 1612 Guess (猜名次)(贪心)
    UVA 11925 Generating Permutations(生成排列)(构造)
    UVA 1611 Crane(起重机)(贪心)
    UVA 10570 Meeting with Aliens(外星人聚会)(暴力枚举)
    【洛谷P1352】没有上司的舞会【树形DP】
  • 原文地址:https://www.cnblogs.com/h-z-y/p/14297002.html
Copyright © 2011-2022 走看看