Netty游戏服务器实战开发(11):Spring+mybatis 手写分库分表策略(续)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_23086307/article/details/83314714

在大型网络游戏中,传统的游戏服务器无法满足性能上的需求。所以有了分布式和微服务新起,在传统web服务器中,我们保存用户等信息基本都是利用一张单表搞定,但是在游戏服务器中,由于要求比较高,我们不能存在大表操作,即分库分表策略。在以前的文章中有关介绍分库分表的,下面我们来实战一下,首先我们做一个这样的计算。

在博主开源的游戏服务器中有这样一个场景:玩家数据保存到player表中,其中将游戏数据库分为100个数据库(可动态扩展),每个库中有player表10张。一张表我们打算最多存放2w条数据。所以我们可以负载总用户=100(库)x10(表)x20000=2千万。

但是我们不可能手动去创建这么多表,所以我们会编写脚本去执行,提供一个sql模板,然后批量去创建库。首先我们要创建100个数据库。脚本如下:

user=root
password=123456
socket=/usr/local/mysql/mysql.sock
mycmd="mysql -u$user -p$password -S $socket"
for  i in `seq 0 99` 
do
#   $mycmd -e "create database game_service_0$i"
  if [ $i -lt 10 ]
  then
    echo create database game_service_0$i"
     mysql -u root -e "create database game_service_0$i"; 
  fi
  if [ $i -ge 10 ]
     then
     echo " create database  game_service$i"
     mysql -u root -e "create database game_service_$i";
  fi 
done 

从脚本中我们可以看到,循环创建100个名称叫做game_service_*数据库。

然后我们在编写脚本来执行sql语句,同样我们编写如下脚本,脚本功能主要是在一百个库里面执行sql文件中的内容

databaseCount=99

databaseBaseName="game_service_"

sql_str=$(cat $1)

for  i in `seq 0 $databaseCount`
do
if [ $i -lt 10 ]
then
db_name=$databaseBaseName"0"$i
echo "executor sql in database $db_name"
mysql -u root  $db_name -e "$sql_str"
echo "executor over"
fi
if [ $i -ge 10 ]
then
db_name1=$databaseBaseName$i
echo "exectuor sql in database $db_name1"
mysql -u root  $db_name1 -e "${sql_str}"
echo "executor over"
fi
done

有了这些简单的脚本我们来编写一个能够创建10个库的sql语句内容如下

/*
 Navicat Premium Data Transfer
 Date: 23/10/2018 20:00:18
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for player_0
-- ----------------------------
DROP TABLE IF EXISTS `player_0`;
CREATE TABLE `player_0`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_1`;
CREATE TABLE `player_1`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_2`;
CREATE TABLE `player_2`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_3`;
CREATE TABLE `player_3`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_4`;
CREATE TABLE `player_4`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `player_5`;
CREATE TABLE `player_5`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `player_6`;
CREATE TABLE `player_6`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_7`;
CREATE TABLE `player_7`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_8`;
CREATE TABLE `player_8`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `player_9`;
CREATE TABLE `player_9`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名称',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金币数量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '钻石数量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家头像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登录时间',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '当前登录时间',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闯关进度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位赛等级(包括历史赛季),规则程序定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等级',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等级',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '经验值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '历史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '战队id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累计充值数量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

当我们执行脚本后得到100个库中有10个表。因此我们准备工作做完。接下来我们要编写程序,使得我们通过用户的uid来定位到用户在某个库中的某个表的位置。。效果图如下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

游戏项目后台在短连接部分玩家数据,所以我们在技术选型上采用spring+mybatis。分库分表的原理我们在

springMVC +mybatis+mysql多套数据源配置
中已经介绍相关的技术。此处省略部分代码,主要讲解一下动态数据源的核心配置。

首先我们来看分库分表策略DbManager



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 分库分表策略
 *
 * @author twjitm - [Created on 2018-10-22 11:50]
 */
public class DbManager {
    private static Logger logger = LoggerFactory.getLogger(DbManager.class);

    /**
     * 分表数量
     */
    private static final int TABLE_SHARING_COUNT = 10;
    /**
     * 分库总数
     */
    private static final int DB_SHARING_COUNT = 100;
    /**
     * 数据库前缀名称
     */
    private static final String DB_BASE_NAME = "game_service_";


    /**
     * 获取数据库名称索引
     *
     * @param playerId 根据玩家的uid来进行分库
     * @return 返回库索引
     */
    public static String getDataBaseName(long playerId) {
        int i = (int) (playerId % DB_SHARING_COUNT);
        if (i < TABLE_SHARING_COUNT) {
            return DB_BASE_NAME + "0" + i;
        } else {
            return DB_BASE_NAME + i;
        }
    }

    /**
     * 获取表索引
     */
    public static int getDataTableIndex(long playerId) {
        return (int) (playerId % DB_SHARING_COUNT);

    }
}

通过程序,我们生成100个jdbc连接,内容太多,没有截图完整。
在这里插入图片描述

然后利用spring 管理这些连写对象,通过程序生成100个连接对象

在这里插入图片描述

然后把这100个连接对象放到一个map集和中,添加一个application-map.xml

在这里插入图片描述

在动态数据源的地方引用这个map

    <!--动态数据源的配置-->
    <bean id="dynamicDataSource" class="com.twjitm.game.server.core.database.mybatis.DynamicDataSource">
        <property name="targetDataSources" ref="dbDataSourceMap"/>
        <!--默认数据源-->
          <property name="defaultTargetDataSource" ref="game_service_00"/>

    </bean>

为了实现分表,我们编写一个基础类,当有需要使用分表的时候,mybatis对应的实体类必须继承此类对象

/**
 * <pre>
 *     需要分表的字段必须继承这个类,并且需要设置index索引
 * <pre/>
 * @author twjitm - [Created on 2018-10-22 11:44]
 */
public class BasePo {
    protected int tableIndex;

    public int getTableIndex() {
        return tableIndex;
    }

    public void setTableIndex(int tableIndex) {
        this.tableIndex = tableIndex;
    }
}

在使用的时候我们在dao层

在这里插入图片描述

后记:上篇文章有小伙伴留言给我说事务配置失效

在这里插入图片描述

在这里插入图片描述

博主我测试没有问题呀?

展开阅读全文

没有更多推荐了,返回首页