Mybatis-Plus-多租户

2.X版本添加多租户

  • 排除jar包内的mybatisplus配置,在主类xxxApplication上添加注解
1
2
@ComponentScan(basePackages = {"com.xxx.web","com.xxx.starter"},
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyBatisPlusConfiguration.class))
  • 添加自定义的配置项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.ISqlInjector;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.parser.ISqlParser;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantHandler;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantSqlParser;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.baomidou.mybatisplus.spring.boot.starter.MybatisPlusProperties;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

/**
* @author cmyang
* @date 2022/12/30 15:47
*/
@Configuration
@EnableConfigurationProperties(MybatisPlusProperties.class)
@MapperScan(basePackages = { "com.xxx.web.cloud.**.mapper" })
public class MybatisPlusConfig {

@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}

@Bean
public GlobalConfiguration globalConfig(ISqlInjector iSqlInjector) {
GlobalConfiguration globalConfig = new GlobalConfiguration();
globalConfig.setSqlInjector(iSqlInjector);
globalConfig.setLogicDeleteValue(CommonConstant.COMMON_YES);
globalConfig.setLogicNotDeleteValue(CommonConstant.COMMON_NO);
globalConfig.setMetaObjectHandler(new CommonMetaObjectHandler());
return globalConfig;
}

/**
* 乐观锁插件
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}

/**
* 多租户和分页插件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
List<ISqlParser> sqlParserList = new ArrayList<>();
TenantSqlParser tenantSqlParser = new TenantSqlParser() {
@Override
public void processInsert(Insert insert) {
// 如果插入已经添加了租户字段,就不再添加
boolean anyMatch = insert.getColumns().stream()
.map(Column::getColumnName).anyMatch("tenant_id"::equals);
if(anyMatch) {
return;
}
super.processInsert(insert);
}

@Override
public boolean allowProcess(MetaObject metaObject) {
// 忽略自动填充多租户的mapper方法
MappedStatement mappedStatement = PluginUtils.getMappedStatement(metaObject);
return !mappedStatement.getId().endsWith("IgnoreTenant");
}
};
tenantSqlParser.setTenantHandler(new TenantHandler() {
@Override
public Expression getTenantId() {
return new LongValue(SecurityUtils.getTenantId());
}

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

@Override
public boolean doTableFilter(String tableName) {
return false;
}
});
sqlParserList.add(tenantSqlParser);
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}

@Bean
public SqlSessionFactory sqlSessionFactoryBean(GlobalConfiguration globalConfiguration,
PaginationInterceptor paginationInterceptor,
OptimisticLockerInterceptor optimisticLockerInterceptor,
DataSource dataSource,
MybatisPlusProperties mybatisPlusProperties) throws Exception {
final MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setGlobalConfig(globalConfiguration);
bean.setPlugins(new Interceptor[]{paginationInterceptor, optimisticLockerInterceptor});
bean.setDataSource(dataSource);
bean.setMapperLocations(mybatisPlusProperties.resolveMapperLocations());
return bean.getObject();
}

@Bean
public CommonMapper commonMapper(SqlSessionFactory sqlSessionFactory){
return new CommonMapper(sqlSessionFactory);
}
}