最近用SpringCloud做项目,顺便实现了一下多租户系统。
代码
package 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 lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author huan
*/
@Slf4j
@Configuration
@EnableTransactionManagement
@MapperScan({"你的Mapper路径,最好用*代替所有"})
@Component
public class MybatisPlusConfig {
/**
* 分页插件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 创建SQL解析器集合
List<ISqlParser> sqlParserList = new ArrayList<>();
// 攻击 SQL 阻断解析器、加入解析链
sqlParserList.add(new BlockAttackSqlParser());
// 创建租户SQL解析器
TenantSqlParser tenantSqlParser = new TenantSqlParser();
// 设置租户处理器
tenantSqlParser.setTenantHandler(new TenantHandler() {
@Override
public Expression getTenantId(boolean select) {
// 设置当前租户ID,实际情况你可以从cookie、或者缓存中拿都行。匹配数据库中的数据
log.debug("当前租户为{}", Objects.requireNonNull("填写你的租户id");
return new LongValue(Objects.requireNonNull("填写你的租户id");
}
@Override
public String getTenantIdColumn() {
// 对应数据库租户ID的列名,是数据库列名,不是实体类
return "tenant";
}
@Override
public boolean doTableFilter(String tableName) {
// 是否需要需要过滤某一张表,false为不过滤
return false;
}
});
sqlParserList.add(tenantSqlParser);
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
}
不过最终没有在我的项目实现,不知道是什么原因。我的实现办法是重写了BaseMapper的增删改查方法。
分析
新增的时候save肯定是带着租户id,这个不用重写;
删除的时候带着id删除,也不用重写;更新同理;
查询时候需要where tenant_id='',所以重写了一下查询方法。
示例代码 (service层)
/**
* 利用租户字段进行增删改查测试
* 查询测试
*
* @return
*/
@Override
public List<TemplateData> selectList() {
QueryWrapper<TemplateData> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("tenant", AESUtils.aesEncode(AppConfig.getAesKey(), AppConfig.getId()));
String a = AESUtils.aesEncode(AppConfig.getAesKey(), AppConfig.getId());
System.out.println(a);
return baseMapper.selectList(queryWrapper);
}
这样就实现了查询时候会自动添加租户id的查询语句了。
备注
也可以参考一下大佬们的: