• ShardingJdbc垂直分库及公共表


     前面已经介绍过,垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器
    上,它的核心理念是专库专用。接下来看一下如何使用Sharding-JDBC实现垂直分库。
    (1)创建数据库
    创建数据库user_db 的t_user表中

    CREATE TABLE`t_user`(
    `user_id` bigint(20)NOT NULL COMMENT '用户id',
    `fullname` varchar(255)CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户姓名',
    `user_type` char(1) DEFAULT NULL COMMENT'用户类型',
    PRIMARY KEY(`user_id`) USING BTREE
    )ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=Dynamic;

     修改配置信息

    server:
      port: 56081
      servlet:
        context-path: /sharding-jdbc-simple-demo
    spring:
      application:
        name: sharding-jdbc-simple-demo
      http:
        encoding:
          enabled: true
          charset: utf-8
          force: true
      main:
        allow-bean-definition-overriding: true
      shardingsphere:
        datasource:
          #新增一个m2库
          names: m2,m3,m1
          m1:
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.jdbc.Driver
            url: jdbc:mysql://rm-xxxxxx.mysql.rds.aliyuncs.com:3306/order_db_1?useUnicode=true
            username: root
            password: 123456
          m2:
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.jdbc.Driver
            url: jdbc:mysql://rm-xxxxxxxxx.mysql.rds.aliyuncs.com:3306/order_db_2?useUnicode=true
            username: root
            password: 123456
          m3:
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.jdbc.Driver
            url: jdbc:mysql://rm-xxxxxxx.mysql.rds.aliyuncs.com:3306/user_db?useUnicode=true
            username: root
            password: 123456
        sharding:
          tables:
            t_order:
              # 分库策略,以user_id为分片键,分片策略为user_id % 2 + 1,user_id为偶数操作m1数据源,否则操作m2。
              databaseStrategy:
                inline:
                  shardingColumn: user_id
                  algorithmExpression: m$->{user_id % 2 + 1}
              # 指定t_order表的数据分布情况,配置数据节点
              actualDataNodes: m$->{1..2}.t_order_$->{1..2}
              tableStrategy:
                inline:
                  shardingColumn: order_id
                  algorithmExpression: t_order_$->{order_id % 2 + 1}
              # 指定t_order表的分片策略,分片策略包括分片键和分片算法
              keyGenerator:
                type: SNOWFLAKE
                column: order_id
            t_user:
              # 指定t_user表的数据分布情况,配置数据节点
              actualDataNodes: m3.t_user
              tableStrategy:
                inline:
                  shardingColumn: user_id
                  algorithmExpression: t_user
          broadcast-tables: t_dict
        props:
          sql:
            show: true
    mybatis:
      configuration:
        map-underscore-to-camel-case: true
    swagger:
      enable: true
    logging:
      level:
        root: info
        org.springframework.web: info
        com.topcheer.dbsharding: debug
        druid.sql: debug

    /**
     * Created by Administrator.
     */
    @Mapper
    @Component
    public interface UserDao {
    
        /**
         * 新增用户
         * @param userId 用户id
         * @param fullname 用户姓名
         * @return
         */
        @Insert("insert into t_user(user_id, fullname) value(#{userId},#{fullname})")
        int insertUser(@Param("userId") Long userId, @Param("fullname") String fullname);
    
        /**
         * 根据id列表查询多个用户
         * @param userIds 用户id列表
         * @return
         */
        @Select({"<script>",
                " select",
                " * ",
                " from t_user t ",
                " where t.user_id in",
                "<foreach collection='userIds' item='id' open='(' separator=',' close=')'>",
                "#{id}",
                "</foreach>",
                "</script>"
        })
        List<Map> selectUserbyIds(@Param("userIds") List<Long> userIds);
    
        /**
         * 根据id列表查询多个用户
         * @param userIds 用户id列表
         * @return
         */
        @Select({"<script>",
                " select",
                " * ",
                " from t_user t ,t_dict b",
                " where t.user_type = b.code and t.user_id in",
                "<foreach collection='userIds' item='id' open='(' separator=',' close=')'>",
                "#{id}",
                "</foreach>",
                "</script>"
        })
        List<Map> selectUserInfobyIds(@Param("userIds") List<Long> userIds);
    }

    测试插入方法

      @Test
        public void testInsertUser(){
            for (int i = 10 ; i<14; i++){
                Long id = i + 1L;
                userDao.insertUser(id,"姓名"+ id );
            }
    
        }

     测试查询方法:

      @Test
        public void testSelectUserbyIds(){
            List<Long> userIds = new ArrayList<>();
            userIds.add(1L);
            userIds.add(2L);
            List<Map> users = userDao.selectUserbyIds(userIds);
            System.out.println(users);
        }

     

     公共表
    公共表属于系统中数据量较小,变动少,而且属于高频联合查询的依赖表。参数表、数据字典表等属于此类型。可
    以将这类表在每个数据库都保存一份,所有更新操作都同时发送到所有分库执行。接下来看一下如何使用
    Sharding-JDBC实现公共表。
    (1)创建数据库
    分别在user_dborder_db_1order_db_2中创建t_dict表:

    CREATE TABLE `t_dict`(
    `dict_id` bigint(20) NOT NULL COMMENT '字典id',
    `type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典类型',
    `code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典编码',
    `value` varchar(50)CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典值',
    PRIMARY KEY(`dict_id`) USING BTREE
    )ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=Dynamic;
    @Mapper
    @Component
    public interface DictDao {
    
        /**
         * 新增字典
         * @param type 字典类型
         * @param code 字典编码
         * @param value 字典值
         * @return
         */
        @Insert("insert into t_dict(dict_id,type,code,value) value(#{dictId},#{type},#{code},#{value})")
        int insertDict(@Param("dictId") Long dictId, @Param("type") String type, @Param("code") String code, @Param("value") String value);
    
        /**
         * 删除字典
         * @param dictId 字典id
         * @return
         */
        @Delete("delete from t_dict where dict_id = #{dictId}")
        int deleteDict(@Param("dictId") Long dictId);
    
    }

    测试方法:

    @Test
        public void testInsertDict(){
            dictDao.insertDict(3L,"user_type","2","超级管理员");
            dictDao.insertDict(4L,"user_type","3","二级管理员");
        }

     测试删除

     @Test
        public void testDeleteDict(){
            dictDao.deleteDict(3L);
            dictDao.deleteDict(4L);
        }

     测试关联:

    @Test
        public void testSelectUserInfobyIds(){
            List<Long> userIds = new ArrayList<>();
            userIds.add(1L);
            userIds.add(2L);
            List<Map> users = userDao.selectUserInfobyIds(userIds);
            System.out.println(users);
        }

    补充:

    假如有些表没有分库也没有分表,而且有很多的话,应该怎么配置,就开始测试了一下。

    在随便的一个库中建了一个表,没有指定节点,也没有配置别的信息,运行接口直接报错,说不到表。

    个人猜想是不是和前面的库的配置顺序有关系,把表所在的库放在最后面,最后即可查询成功。

  • 相关阅读:
    我是如何折腾.NET Resx资源文件的 当计算机中的资源已经足够多时,我们也要学会尽可能的借用
    当程序开发人员开始抛弃技术时,是否意味着噩梦的开始?抛弃了SQL Server 2000才发现客户的简单问题真的很难解决
    分享.NET ERP项目开发中应用到的重量级工具 选择合适的工具和资源,做项目效率高而且规范程度高
    Management Console ERP项目开发辅助工具 正确的方法+适当的工具使做项目的效率高而且问题少
    ERP系统管理员的工具箱 推荐几款优秀的数据比较同步工具 Data Compare and Sync tool
    亲自下载CSDN社区600万用户数据 设计两条编程题目考验你的.NET编程基础
    知识管理系统Data Solution研发日记之十六 保存服务器文档为本机PDF格式
    【转】好的学习方法
    iPhone开发学习笔记[7/50]在xcode里配置成功subversion
    iPhone开发学习笔记[4/50]表视图的使用
  • 原文地址:https://www.cnblogs.com/dalianpai/p/12316719.html
Copyright © 2020-2023  润新知