mybatis-plus配置租户隔离和分页插件教程及遇到的坑

mybatis-plus配置租户隔离和分页插件教程及遇到的坑

  1. 先说分页插件配置:
  • 官网交代的很清除,细节处理都被封装好了,我们只需要在配置类加入下面代码就完成了分页插件的装配。
    /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
        // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
        return interceptor;
    }

这里贴图官网(https://baomidou.com/plugins/tenant/)的配置代码:
在这里插入图片描述

  • 如何使用呢?
  • 答:配置了分页插件后,在*Mapper.xml中如果有分页需求,那么不需要自己实现count();去查总数,只需要在参数中传入Page<?> page, 就行了,mybatis-plus的分页插件会自动配置count();并将相应的结果封装到Page的实现中去。具体传参代码如下:
/**
     * 查询列表
     *
     * @param page 分页对象
     * @param params 筛选条件
     * @return 分页列表
     */
    List<?> findList(Page<?> page, @Param("params") Map<String, Object> params);

/**
* 如果想要获取条件筛选的总数,只需要调用:page.getTotal()即可
*/

至此分页插件配置完成

  1. 再来说说租户隔离插件配置
  • 官网交代的也很清楚,第一步先创建一个租户参数配置的处理器:

//这个是官方的默认配置
@Component
public class CustomTenantHandler implements TenantLineHandler {

    @Override
    public Expression getTenantId() {
        // 假设有一个租户上下文,能够从中获取当前用户的租户
         Long tenantId = TenantContextHolder.getCurrentTenantId();
        // 返回租户ID的表达式,LongValue 是 JSQLParser 中表示 bigint 类型的 class
        return new LongValue(tenantId);;
    }

    @Override
    public String getTenantIdColumn() {
        return "tenant_id";
    }

    @Override
    public boolean ignoreTable(String tableName) {
        // 根据需要返回是否忽略该表
        return false;
    }

}


//这里是我自定义了一部分参数的配置
@Component
public class CustomTenantHandler implements TenantLineHandler {

//这东西就是一个属性存储的工具类
    @Autowired
    TenantProperties tenantProperties;

    @Override
    public Expression getTenantId() {
        // 假设有一个租户上下文,能够从中获取当前用户的租户,这个TenantContextHolder代码后面我会贴出来,他的主要作用就是存储当前请求的租户标识,比如tenant_id
        String tenantId = TenantContextHolder.getTenant();
        // 返回租户ID的表达式
        return new StringValue(tenantId);
    }

    @Override
    public String getTenantIdColumn() {
    //这里配置租户字段名,和数据库的租户字段保持一致即可
        return tenantProperties.getFieldName();
    }

    @Override
    public boolean ignoreTable(String tableName) {
        // 根据需要返回是否忽略该表,这里的List<String> ignoreTables 是一个携带MySQL表名称
        //的List,tableName就是当前请求所访问的表名称
        List<String> ignoreTables = tenantProperties.getIgnoreTable();
        return !ignoreTables.isEmpty() && ignoreTables.contains(tableName);
    }

}


//租户id存储的工具类
public class TenantContextHolder {
    /**
     * 支持父子线程之间的数据传递
     */
    private static final ThreadLocal<String> CONTEXT = new TransmittableThreadLocal<>();

//这个用来存租户id
    public static void setTenant(String tenant) {
        CONTEXT.set(tenant);
    }
//这个用来获取已经存储的租户id
    public static String getTenant() {
        return CONTEXT.get();
    }
//这个用来清除当前线程存储的租户id。一般而言,对于租户id的set应该在请求处理前的拦截器中,
//而请求处理完成后的拦截器应该将当前请求存储的租户id清除,避免内存泄漏
    public static void clear() {
        CONTEXT.remove();
    }
}


//这里贴一个关于租户默认属性的常量类
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "ilycq.tenant")
public class TenantProperties {
    /**
     * 是否开启多租户
     */
    private Boolean enable = false;
    /**
     * 开启的租户类型(client,org),默认client
     */
    private String type = "org";

    /**
     * 租户对应字段名,默认tenant_id
     */
    private String fieldName = "";

    /**
     * 配置不进行多租户隔离的表名
     */
    private List<String> ignoreTable  = new ArrayList<>();
}
  • 第二步,将上面创建好的租户处理器加入配置类中的MybatisPlusInterceptor拦截器,代码如下:
@SpringBootConfiguration
public class MybatisPlusAutoConfigure {

    @Autowired
    private CustomTenantHandler customTenantHandler;

    @Autowired
    private TenantProperties tenantProperties;

    /**
     * 插件配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        if (tenantProperties.getEnable()) {
            //注册租户插件
            interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(customTenantHandler));
        }
        //注册分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

到这里分页插件和租户隔离就都配置成功了

  • tips
    • 如果只想给某一条sql过滤租户配置,使用注解 @InterceptorIgnore(tenantLine = “1”)
	@InterceptorIgnore(tenantLine = "1")
    List<?> getWholeList(@Param("params") Map<String, Object> params);
  1. 讲一下我遇到的坑:
  • 首次配置完租户和分页插件后,在测试时发现分页列表中的总条数和 page.getTotal(); 的数值不同,我大为震惊,赶紧上百度图书馆博览群书,找了一圈,试了许多方法,然;并;卵(然而并没有什么卵用),又在官网仔细找了找,发现官方也没有交代。
  • 还好过了不多一会儿,歪打正着的解决了。
  • 说说解决方案:
    • 出现问题的原因很清楚,就是在查询分页列表的时候,查询列表的sql中插入了租户,但是分页插件的Count();函数中并没有插入租户。于是我检查了我的代码,发现在我的配置类中,先将分页插件注册到拦截其中,再将租户插件注册到拦截器中,我就在想,将他们的注册顺序调换一下就是不是就可以了,没想到还真是这样。
//错误的配置顺序:先配置了分页,再配置租户,这样配置的后果就是page.getTotal();的数值和实际数值不符。
/**
     * 插件配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //注册分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
        if (tenantProperties.getEnable()) {
            //注册租户插件
            interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(customTenantHandler));
        }
    }

//正确的配置顺序,先配置租户过滤器,再配置分页过滤器,前文贴出的代码按照此顺序配置
    /**
     * 插件配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        if (tenantProperties.getEnable()) {
            //注册租户插件
            interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(customTenantHandler));
        }
        //注册分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis-Plus 是一个基于 MyBatis 的增强工具,提供了一些额外的功能和便利的配置。下面是一些常见的 MyBatis-Plus 配置: 1. 添加依赖:在项目的 `pom.xml` 文件中添加 MyBatis-Plus 的依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>latest-version</version> </dependency> ``` 2. 配置数据源:在 Spring Boot 的配置文件(`application.properties` 或 `application.yml`)中配置数据源信息,例如: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/my_database username: root password: my_password driver-class-name: com.mysql.cj.jdbc.Driver ``` 3. 配置 MyBatis-Plus:创建一个配置类,用于配置 MyBatis-Plus 相关的配置项,例如: ```java @Configuration @MapperScan("com.example.mapper") // 指定 Mapper 类所在的包路径 public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } } ``` 4. 创建实体类和 Mapper 接口:创建与数据库表对应的实体类和对应的 Mapper 接口,使用 MyBatis-Plus 的注解进行配置。例如: ```java @Data @TableName("user") public class UserEntity { @TableId(type = IdType.AUTO) private Long id; private String username; private Integer age; // 省略 getter 和 setter } ``` ```java public interface UserMapper extends BaseMapper<UserEntity> { // 可以直接使用 MyBatis-Plus 提供的方法,也可以自定义 SQL 方法 } ``` 这些是 MyBatis-Plus 的基本配置,你还可以根据需求进行一些高级配置,例如分页插件、逻辑删除、多租户等。具体的配置和使用方法可以参考 MyBatis-Plus 的官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值