我无论作什麽,始终在想着,只要我的精力允许我的话,我就要首先为我的祖国服务。——巴甫
个人理解的多租户:一套产品提供给多个企业使用,每家企业之间的数据相互隔离。例如我有一套运输管理系统,开发完成后,每一家企业购买我们的产品,我只需要提供一个账号,即可拥有完整的内容。如权限管理、订单管理等,他们之间的数据是不互通的
我们可以通过在每张表上加一个租户id去实现这个功能
我们的mybatis-plus版本为3.1.0,这里放上依赖
| <!--    mybatis-plus    --><dependency>
 <groupId>com.baomidou</groupId>
 <artifactId>mybatis-plus-boot-starter</artifactId>
 <version>3.1.0</version>
 </dependency>
 
 | 
然后我们需要修改配置文件
| mybatis-plus:
 config-location: classpath:/mybatis/mybatis-config.xml
 mapper-locations:
 - classpath*:com/ruben/dao/xml/*Mapper.xml
 configuration-properties:
 prefix:
 boolValue: TRUE
 blobType: BLOB
 global-config:
 sql-parser-cache: true
 
 | 
关键是最下面两行sql-parser-cache: true
然后我们需要在Mybatis-Plus的配置类中进行配置
我们之前注入的分页拦截器PaginationInterceptor
当时是这么写的
| @Beanpublic PaginationInterceptor paginationInterceptor() {
 return new PaginationInterceptor();
 }
 
 | 
现在我们加上配置
| package com.ruben.config;
 import com.baomidou.mybatisplus.core.parser.ISqlParser;
 import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
 import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
 import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.LongValue;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 import java.util.ArrayList;
 import java.util.List;
 
 
 
 
 
 
 
 
 
 
 @Configuration
 @MapperScan("com.ruben.dao.mapper*")
 public class MybatisPlusConfig {
 
 @Bean
 public PaginationInterceptor paginationInterceptor() {
 PaginationInterceptor interceptor = new PaginationInterceptor();
 List<ISqlParser> sqlParserList = new ArrayList<>();
 sqlParserList.add(new BlockAttackSqlParser());
 TenantSqlParser tenantSqlParser = new TenantSqlParser();
 tenantSqlParser.setTenantHandler(new TenantHandler() {
 @Override
 public Expression getTenantId() {
 
 return new LongValue(1);
 }
 
 @Override
 public String getTenantIdColumn() {
 
 return "tenant_id";
 }
 
 @Override
 public boolean doTableFilter(String tableName) {
 
 return false;
 }
 });
 sqlParserList.add(tenantSqlParser);
 interceptor.setSqlParserList(sqlParserList);
 return interceptor;
 }
 }
 
 | 
别忘了在数据库中的表加上字段tenant_id,如果我们的表非常多,可以参考我这篇博客统一加字段
然后如果我们有些sql或者函数不需要加租户条件,则可以使用@SqlParser(filter = true)注解

不过注意,只能在extends com.baomidou.mybatisplus.core.mapper.BaseMapper的类中函数上加该注解才能生效
我们简单测试一下
| @Testpublic void list() {
 List<UserPO> userList = mpUserMapper.findUserList(UserPO.builder().username("ruben").build());
 userList.forEach(System.out::println);
 LambdaQueryWrapper<UserPO> wrapper = Wrappers.lambdaQuery(UserPO.builder().build());
 wrapper.select(w -> true).inSql(UserPO::getId, "select id from user");
 mpUserMapper.selectList(wrapper);
 }
 
 | 

这里红色打印出来的sql就是我们刚刚加了@SqlParser(filter = true)注解的函数
下面蓝色则是使用mybatis-plus封装好的selectList方法,可以看出蓝色里我们配置了租户id后的结果,默认加上了 user.tenant_id = 1条件
这样每个租户之间就实现了相互隔离,非常便利~