当前位置: 代码网 > it编程>编程语言>Java > MyBatis-Plus使用动态表名分表查询的实现

MyBatis-Plus使用动态表名分表查询的实现

2025年11月28日 Java 我要评论
动态修改表名的场景通常用于:分表策略:根据不同的条件(如年份、月份、区域等)来选择查询不同的表。多租户系统:根据租户的不同,查询不同的表。历史数据管理:查询历史表的数据时,动态决定表名(例如每年有一个

动态修改表名的场景通常用于:

  • 分表策略:根据不同的条件(如年份、月份、区域等)来选择查询不同的表。
  • 多租户系统:根据租户的不同,查询不同的表。
  • 历史数据管理:查询历史表的数据时,动态决定表名(例如每年有一个对应的表,table_2021, table_2022 等)。

1. 引入依赖

 <dependency>
     <groupid>com.baomidou</groupid>
     <artifactid>mybatis-plus-boot-starter</artifactid>
     <version>3.5.3</version>   
 </dependency>

注意:版本须使用3.5.3以上,否则无法使用dynamictablenameinnerinterceptor类中的settablenamehandler方法

2. mybatis-plus配置

@configuration
@slf4j
public class mybatisplusconfig {

    @bean
    public mybatisplusinterceptor mybatisplusinterceptor() {
        mybatisplusinterceptor mybatisplusinterceptor = new mybatisplusinterceptor();
        // 数据权限
        //mybatisplusinterceptor.addinnerinterceptor(new datafilterinterceptor());
        // 乐观锁
        mybatisplusinterceptor.addinnerinterceptor(new optimisticlockerinnerinterceptor());
        // 防止全表更新与删除
        mybatisplusinterceptor.addinnerinterceptor(new blockattackinnerinterceptor());
        //动态表名
        dynamictablenameinnerinterceptor dynamictablenameinnerinterceptor = new dynamictablenameinnerinterceptor();
        dynamictablenameinnerinterceptor.settablenamehandler((sql, tablename) -> { //匿名内部类
            string tenant = tenantcontext.tenant_data.get();
            // 如果不为空,使用动态表名。
            if (stringutils.isnotblank(tenant) && tenantcontext.containstablename(tablename)) {
                log.info("dynamictablename -- >tablename={}, tenant={}",tablename, tenant);
                return tablename + "_" + tenant;
            }
            return tablename;
        });
        mybatisplusinterceptor.addinnerinterceptor(dynamictablenameinnerinterceptor);
        // 分页插件
        mybatisplusinterceptor.addinnerinterceptor(new paginationinnerinterceptor());
        return mybatisplusinterceptor;
    }
}

3. tenantcontext 类:租户上下文管理器

public class tenantcontext {

    // 需要替换的动态表名
    public static threadlocal<string> tenant_data = new threadlocal<>();

    //用于记录哪些表可以使用该动态表名处理器
    private static list<string> tablenames = arrays.aslist("test_user");

    //设置请求线程的租户数据
    public static void settenantdata(string tenant) {
        tenant_data.set(tenant);
    }

    //删除当前请求线程的租户数据
    public static void removeyeardata() {
        tenant_data.remove();
    }

    public static boolean containstablename(string tablename) {
        if (tablenames.contains(tablename)) {
            return true;
        }
        return false;
    }

}

4. 实体类

@data
@tablename("test_user")
public class testuser implements serializable {
    private string id;
    private string name;
    private string managerid;
    private string salary;
    private string age;
    private string departid;
    private string remark;
    private string province;
}

5. 具体实现

@restcontroller
@slf4j
public class testcontroller {

    @resource
    private itestuserservice testuserservice;

    @getmapping("/selectlist")
    public list<testuser> selectlist(@requestparam string tenant) {
        return testuserservice.selectlist(tenant);
    }
}

public interface itestuserservice extends iservice<testuser> {

    list<testuser> selectlist(string tenant);
}

@service
public class testuserserviceimpl extends serviceimpl<testusermapper, testuser> implements itestuserservice {

    @overridejava
    public list<testuser> selectlist(string tenant) {
        tenantcontext.settenantdata(tenant);
        wrapper<testuser> querywrapper = new querywrapper<>();
        return basemapper.selectlist(querywrapper);
    }
}

到此这篇关于mybatis-plus使用动态表名分表查询的实现 的文章就介绍到这了,更多相关mybatis-plus 动态表查询内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com