使用mybatisplus插件实现按时间分表及默认查询

pom 需3.4.版本及以上

<mybatis-plus-spring-boot.version>3.4.1</mybatis-plus-spring-boot.version>

定义及注册mybatisplus插件

package com.xxx.wxxms.mybatis;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {

        Map<String, TableNameHandler> tableNameHandlerMap = new HashMap<>();
        MonthTableNameHandler wms_dev_ins_history = new MonthTableNameHandler();
        tableNameHandlerMap.put(wms_dev_ins_history.getTableNames(), wms_dev_ins_history);

        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandlerMap(tableNameHandlerMap);

        //以拦截器的方式处理表名称
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        return interceptor;
    }

}

package com.xxx.wxxms.mybatis;

import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;

public class MonthTableNameHandler implements TableNameHandler {

    //用于记录哪些表可以使用该月份动态表名处理器(即哪些表按月分表)
    private String tableNames = "wms_devins_history";

    public String getTableNames() {
        return this.tableNames;
    }

    //每个请求线程维护一个month数据,避免多线程数据冲突。所以使用ThreadLocal
    private static final ThreadLocal<String> MONTH_DATA = new ThreadLocal<>();

    //设置请求线程的month数据
    public static void setData(String month) {
        MONTH_DATA.set(month);
    }

    //删除当前请求线程的month数据
    public static void removeData() {
        MONTH_DATA.remove();
    }

    @Override
    public String dynamicTableName(String sql, String tableName) {
        if (this.tableNames.contains(tableName)){
            return tableName + "_" + MONTH_DATA.get();  //表名增加月份后缀
        }else{
            return tableName;   //表名原样返回
        }
    }

}

package com.xxx.xxx.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxx.common.core.utils.DateUtils;
import com.xxx.common.core.utils.bean.BeanUtils;
import com.xxx.common.core.web.domain.AjaxResult;
import com.xxx.wxxms.api.domain.DongHuanDevIns;
import com.xxx.wxxms.domain.entity.WmsDevinsHistoryEntity;
import com.xxx.wxxms.mapper.WmsDevinsHistoryMapper;
import com.xxx.wxxms.mybatis.MonthTableNameHandler;
import com.xxx.wxxms.service.WmsDevinsHistoryService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
@Slf4j
public class WmsDevinsHistoryServiceImpl extends ServiceImpl<WmsDevinsHistoryMapper, WmsDevinsHistoryEntity> implements WmsDevinsHistoryService {

    @Override
    public AjaxResult syncDevInsHistory(List<DongHuanDevIns> devInsList) {

        String month = DateUtils.getYearMonth();
        Integer tableExist = baseMapper.isTableExist(month);

        MonthTableNameHandler.setData(month);
        if(tableExist == null || tableExist ==0){
            baseMapper.createNewTable();
        }

        List<WmsDevinsHistoryEntity> list = new ArrayList<>();
        for (DongHuanDevIns devIns :devInsList){
            WmsDevinsHistoryEntity devinsHistory = new WmsDevinsHistoryEntity();
            BeanUtils.copyBeanProp(devinsHistory, devIns);
            list.add(devinsHistory);
        }
        baseMapper.insertDevinsHistory(list);

        MonthTableNameHandler.removeData();
        return AjaxResult.success();
    }
}

/**
 * 日期路径 即年/月/日 如201808
 */
public static final String getYearMonth()
{
    return DateFormatUtils.format(new Date(), "yyyyMM");
}

判断表是否存在及创建新表(create table wxxms_history like wxxms_history中,默认会将日期后缀添加到第一个wxxms_history后面)

<select id="isTableExist" parameterType="string" resultType="int">
    select count(*) from information_schema.TABLES where table_name = concat('wxxms_history_', #{table_extra})
</select>

<update id="createNewTable">
    create table wxxms_history like wxxms_history;
</update>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis-Plus 是 MyBatis 的增强工具,在 MyBatis 的基础上进行了扩展和增强,提供了更加便捷的 CRUD 操作、代码生成器等功能。MyBatis-Plus 也支持分表查询,具体实现方式如下: 1. 定义分表规则 在 MyBatis-Plus 中,我们可以通过自定义分表规则来实现分表查询。可以自定义一个分表策略类,用于根据查询条件生成对应的表名或分库分表信息。例如,我们可以定义一个以用户 ID 为分表依据的分表策略类: ```java public class UserTableShardStrategy implements IShardTableStrategy { @Override public String getTargetTableName(String tableName, Object params, String mapperId) { if (params == null) { throw new IllegalArgumentException("params can not be null."); } int userId = Integer.parseInt(params.toString()); int tableIndex = userId % 10; return tableName + "_" + tableIndex; } } ``` 这里我们将用户 ID 对 10 取模,得到一个在 0~9 范围内的数字,然后将分表后缀拼接到原表名后面,得到分表的表名。 2. 在实体类中定义分表字段 在实体类中,我们需要定义分表字段,用于指定分表规则的依据字段。例如,在 User 实体类中,我们可以定义一个 userId 字段来作为分表规则的依据。 ```java @Data public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; @TableField(value = "user_id", exist = true) private Integer userId; } ``` 这里我们使用了 `@TableField` 注解来标识 userId 字段对应的表字段名为 `user_id`,并且设置了 `exist=true`,表示该字段在数据库中存在。 3. 在 Mapper 中使用分表规则 在 Mapper 中,我们可以使用 MyBatis-Plus 的分表插件实现分表查询。在 SQL 语句中,我们可以使用 `#{}` 占位符来引用分表参数。例如: ```xml <select id="getUserById" resultType="User"> SELECT * FROM user WHERE user_id = #{userId} </select> ``` 这里的 `#{userId}` 表示根据用户 ID 计算出分表后缀,然后将其拼接到 `user` 后面,得到最终的表名。 4. 注册分表插件 最后,我们需要在 MyBatis 的配置文件中注册分表插件,以便让 MyBatis-Plus 自动识别并处理分表查询语句。 ```xml <plugins> <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.inner.ShardTableInnerInterceptor"> <property name="shardTableStrategy" value="com.example.mybatisplusdemo.shard.UserTableShardStrategy"/> </plugin> </plugins> ``` 这里我们使用了一个 ShardTableInnerInterceptor 插件,它会在执行查询前根据分表规则自动修改 SQL 语句中的表名。需要注意的是,这里的 `com.example.mybatisplusdemo.shard.UserTableShardStrategy` 应该替换为你自己定义的分表策略类的全限定名。 以上就是使用 MyBatis-Plus 实现分表查询的基本步骤。需要注意的是,分表查询会增加系统的复杂度和维护难度,需要谨慎使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值