在之前的文章《使用mybatis-plus完成多租户的saas系统》我们介绍了使用mybatis-plus来应用多租户,但是由于当时没有贴源码,有部分同学使用的时候还是比较模糊,因此这里的话,我们再介绍一个更清晰的改进版来演示一下,并且贴上源码。
这里使用多租户的时候,其实我们的核心就是使用mybatis的这个TenantLineInnerInterceptor这个类,下面我们开始演示下:
1、这里我们准备一个空白的mybatis plus项目
这里假设我们已经准备好了,并且提供了一个接口:
这个接口我们用来请求用户,这里整个sql里面的数据是:
这里我们把项目启动起来,然后请求下这个getlist的接口:
可以看到查询的是数据库里面所有人的数据,然后我们看下日志,查询的sql:
这里执行的sql是原始的sql,不带任何where查询条件。
2、演示多租户
在数据库里面我们可以看到有一个tenant_id的字段,代表的就是多租户的信息,这里数据库里面分别有租户1,租户2,所以我们在真实的业务场景里面,我们希望租户1查询的是租户1的数据,租户2查询的是租户2的数据,因此这里我们就需要添加一个mybatisplusconfig文件,然后加载下Tenant信息,这里我们的mybatisPlusConfig示例代码如下:
package cn.nieqing.mybatisplus.config; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.schema.Column; @Configuration @EnableTransactionManagement @Slf4j public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(HttpServletRequest request) { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(tenantLineInnerInterceptor()); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } @Bean public TenantLineInnerInterceptor tenantLineInnerInterceptor() { return new TenantLineInnerInterceptor(new TenantLineHandler() { @Override public Expression getTenantId() { String tid = this.getTenantIdFromHeader(); log.info("获取到的tid是:{}",tid); return new StringValue(tid); } private String getTenantIdFromHeader() { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); HttpServletRequest servletRequest = requestAttributes.getRequest(); return servletRequest.getHeader("tid"); } @Override public String getTenantIdColumn() { return "tenant_id"; } @Override public boolean ignoreTable(String tableName) { return false; } @Override public boolean ignoreInsert(List<Column> columns, String tenantIdColumn) { return TenantLineHandler.super.ignoreInsert(columns, tenantIdColumn); } }); } }
这里主要分2步,我们挨个来说一下。
1、首先定义一个tenantlineinerinterceptor,这里是定义核心租户的地方,里面需要定义的是数据库表里面的租户字段:
public String getTenantIdColumn()
还要让每次拦截的时候获取当前的租户id
public Expression getTenantId()
我们在获取当前租户id的时候,这里我们演示的是直接从httprequest的头里面获取数据,核心代码是:
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); HttpServletRequest servletRequest = requestAttributes.getRequest(); return servletRequest.getHeader("tid");
2、定义好拦截器之后,我们需要把这里的tenantlineinerinterceptor添加到mybatis plus的配置里面去,核心代码是:
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(tenantLineInnerInterceptor()); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor;
到此为止我们就完成了多租户的开发了。然后我们把项目启动起来,在请求的时候我们在requestheader里面带上tid
可以看到我们带上tid=1的时候,查询出来的信息就只有tenant_id为1的用户数据,我们看看日志:
这里的sql会自动为我们添加上where查询条件的tenant_id。然后我们把tid修改为2在测试看看:
可以看到这里查询出来的都是tenant_id=2的用户数据,查看日志,也匹配了最新的2,如下图:
备注:
1、这里主要是利用mybatis_plus的拦截器来自动添加查询条件完成的,当然除了查询,新增,修改都是好使的。
2、我们利用这个mybatis_plus提供的多租户的插件,可以很方便的开发saas系统。
最后按照惯例,附上本案例的源码,登录后即可下载。
还没有评论,来说两句吧...