springboot+mybatis实现自定义分表

在做基于mybatis持久层开发时,由于单表数据量增大,可能会考虑分表进行处理,可以采用sharding-jdbc实现,这里基于mybatis自定义实现分表组件进行实现,重点思考其实现逻辑和设计模式,学习底层原理。
具体涉及到的多表联查,可进一步思考如何实现。
分表需求:自定义分表策略,可以为id取模,日期取月;可以通过注解进行引用;
前提:需提取建好表结构;
核心逻辑:通过拦截器,根据分表策略得到分表名,再把分表名动态替换到sql中;
实例:
分表策略及实现

public interface ITableShardStrategy {

    /**
     * 生成分表名
     * @param tableNamePrefix 表前缀名
     * @param value 值
     * @return: String
     */
    String generateTableName(String tableNamePrefix,Object value);

    /**
     * 验证tableNamePrefix
     * @param tableNamePrefix 表前缀名
     * @return:
     */
    default void verificationTableNamePrefix(String tableNamePrefix){
        if (ObjectUtils.isEmpty(tableNamePrefix)) {
            throw new RuntimeException("tableNamePrefix is null");
        }
    }
}

id取模策略

@Component
public class IdTableShardStrategy implements ITableShardStrategy {

    @Override
    public String generateTableName(String tableNamePrefix, Object value) {
        verificationTableNamePrefix(tableNamePrefix);
        if (value == null || ObjectUtils.isEmpty(value.toString())) {
            throw new RuntimeException("value is null");
        }
        long id = Long.parseLong(value.toString());
        //此处可以缓存优化
        return tableNamePrefix + "_" + (id % 2);
    }
}

日期取月策略

@Component
public class DateTableShardStrategy implements ITableShardStrategy {

    private static final String DATE_PATTERN = "yyyyMM";

    @Override
    public String generateTableName(String tableNamePrefix, Object value) {
        verificationTableNamePrefix(tableNamePrefix);
        if (value == null || ObjectUtils.isEmpty(value.toString())) {
            return tableNamePrefix + "_" + DateUtil.formatDateByPattern(new Date(), DATE_PATTERN);
        } else {
            return tableNamePrefix + "_" + DateUtil.formatDateByPattern(new Date(), value.toString());
        }
    }
}

通过注解引入,灵活应用,注解的作用范围是类、接口、函数,运行时生效。

@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TableShard {

    // 表前缀名
    String tableNamePrefix();

    // 值
    String value() default "";

    // 是否是字段名,如果是需要解析请求参数改字段名的值(默认否)
    boolean fieldFlag() default false;

    // 对应的分表策略类
    Class<? extends ITableShardStrategy> shardStrategy();

}

抽象分表策略与分表注解都搞定了,最后一步就是根据分表注解信息,去执行分表策略得到分表名,再把分表名动态替换到sql中,同时具有通用性。

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值