首页 > 作文

基于MybatisPlus插件TenantLineInnerInterceptor实现多租户功能

更新时间:2023-04-03 23:03:05 阅读: 评论:0

多租户技术的基本概念:

多租户技术(英语:multi-tenancy technology)或称多重租赁技术,是一种软件架构技术,它是在探讨与实现如何于多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。
在云计算的加持之下,多租户技术被广为运用于开发云各式服务,不论是iaas,paas还是saas,都可以看到多租户技术的影子。

前面介绍过gitegg框架与数据库交互使用了mybatis增强工具mybatis-plus,mybatis-plus提供了tenantlineinnerinterceptor租户处理器来实现多租户功能,其原理就是mybatis-plus实现了自定义mybatis拦截器(interceptor),在需要执行的sql后面自动添加租户的查询条件,实际和分页插件,数据权限拦截器是同样的实现方式。

简而言之多租户技术就是可以让一套系统通过配置给不同的客户提供服务,每个客户看到的数据都是属于自己的,就好像每个客户都拥有自己一套独立完善的系统。

下面是在gitegg系统的应用配置:

1、在gitegg-platform-mybatis工程下新建多租户组件配置文件tenantproperties.java和tenantconfig.java,tenantproperties.java用于系统读取配置文件,这里会在nacos配置中心设置多组户的具体配置信息,tenantconfig.java是插件需要读取的配置有三个配置项:
tenantid租户id、tenantidcolumn多租户的字段名、ignoretable不需要多租户隔离的表。
tenantproperties.java:

package com.gitegg.platform.mybatis.props;import lombok.data;import org.springframework.boot.context.properties.configurationproperties;import org.springframework.context.annotation.configuration;import java.util.list;/** * 白名单配置 */@data@configuration@configurationproperties(prefix = "tenant")public class tenantproperties {    /**     * 是否开启租户模式     */    private boolean enable;    /**     * 多租户字段名称     */    private string column;    /**     * 需要排除的多租户的表     */    private list<string> exclusiontable;}

tenantconfig.java:

package com.gitegg.platform.mybatis.config;import com.baomidou.mybatisplus.extension.plugins.handler.tenantlinehandler;import com.baomidou.mybatisplus.extension.plugins.inner.tenantlineinnerinterceptor;import com.gitegg.platform.boot.util.giteggauthutils;import com.gitegg.platform.mybatis.props.tenantproperties;import lombok.requiredargsconstructor;import net.sf.jsqlparr.expression.expression;import net.sf.jsqlparr.expression.nullvalue;import net.sf.jsqlparr.expression.stringvalue;import org.springframework.beans.factory.annotation.autowired;import org.springframework.boot.autoconfigure.autoconfigurebefore;import org.springframework.context.annotation.bean;import org.springframework.context.annotation.configuration;/** * 多租户配置中心 * * @author gitegg */@configuration@requiredargsconstructor(onconstructor_ = @autowired)@autoconfigurebefore(mybatisplusconfig.class)public class tenantconfig {private final tenantproperties tenantproperties;/** * 新多租户插件配置,一缓和二缓遵循mybatis的规则, * 需要设置 mybatisconfiguration#udeprecatedexecutor = fal * 避免缓存万一出现问题 * * @return tenantlineinnerinterceptor */@beanpublic tenantlineinnerinterceptor tenantlineinnerinterceptor() {return new tenantlineinnerinterceptor(new tenantlinehandler() {/** * 获取租户id * @return expression */@overridepublic expression gettenantid() {string tenant = giteggauthutils.gettenantid();if (tenant != null) {return new stringvalue(giteggauthutils.gettenantid());}return new nullvalue();}/** * 获取多租户的字段名 * @return string */@overridepublic string gettenantidcolumn() {return tenantproperties.getcolumn();}/** * 过滤不需要根据租户隔离的表 * 这是 default 方法,默认返回 fal 表示所有表都需要拼多租户条件 * @param tablename 表名 */@overridepublic boolean ignoretable(string tablename) {return tenantproperties.getexclusiontable().stream().anymatch((t) -> t.equalsignoreca(tablename));}});}}

2、可在工程下新建application.yml,配置将来需要在nacos上配置的信息:

tenant:  # 是否开启租户模式  enable: true  # 需要排除的多租户的表  exclusiontable:    - "t_sys_district"    - "oauth_client_details"  # 租户字段名称  column: tenant_id

3、修改mybatisplusconfig.java,把多租户过滤器加载进来使其生效:

package com.gitegg.platform.mybatis.config;import com.baomidou.mybatisplus.annotation.dbtype;import com.baomidou.mybatisplus.extension.plugins.mybatisplusinterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.blockattackinnerinterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.optimisticlockerinnerinterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.paginationinnerinterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.tenantlineinnerinterceptor;import com.gitegg.platform.mybatis.props.tenantproperties;import lombok.requiredargsconstructor;import org.病假申请mybatis.spring.annotation.mapperscan;import org.springframework.beans.factory.annotation.autowired;import org.springframework.context.annotation.bean;import org.springframework.context.annotation.configuration;@configuration@requiredargsconstructor(onconstructor_ = @autowired)@mapperscan("com.gitegg错别字广告语.**.mapper.**")public class mybatisplusconfig {    private final tenantlineinnerinterceptor tenantlineinnerinterceptor;    private final tenantproperties tenantproperties;    /**     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 mybatisconfiguration#udeprecatedexecutor = fal     * 避免缓存出现问题(该属性会在旧插件移除后一同移除)     */    @bean    public mybatisplusinterceptor mybatisplusinterceptor() {        mybatisplusinterceptor interceptor = new mybatisplusinterceptor();        //多租户插件        if (tenantproperties.getenable()) {            interceptor.addinnerinterceptor(tenantlineinnerinterceptor);        }        //分页插件        interceptor.addinnerinterceptor(new paginationinnerinterceptor(dbtype.mysql));        //防止全表更新与删除插件: blockattackinnerinterceptor        blockattackinnerinterceptor blockattackinnerinterceptor = new blockattackinnerinterceptor();        interceptor.addinneri背单词的方法nterceptor(blockattackinnerinterceptor);        return interceptor;    }    /**     * 乐观锁插件 当要更新一条记录的时候,希望这条记录没有被别人更新     * /d/file/titlepic/interceptor-optimistic-locker.html     */    @bean    public optimisticlockerinnerinterceptor optimisticlockerinterceptor() {        return new optimisticlockerinnerinterceptor();    }}

4、在giteggauthutils方法中新增获取租户信息的公共方法,租户信息在gateway进行转发时进行设置,后面会说明如何讲租户信息设置到header中:

package com.gitegg.platform.boot.util;import cn.hutool.json.jsonutil;import com.gitegg.platform.ba.constant.authconstant;import com.gitegg.platform.ba.domain.giteggur;import org.springframework.util.stringutils;import javax.rvlet.http.httprvletrequest;import java.io.unsupportedencodingexception;import java.net.urldecoder;public class giteggauthutils {    /**     * 获取用户信息     *     * @return giteggur     */    public static giteggur getcurrentur() {        httprvletrequest request = giteggwebutils.getrequest();        if (request == null) {            return null;        }        try {            string ur = request.getheader(authconstant.header_ur);            if (stringutils.impty(ur))            {                return null;            }            string urstr = urldecoder.decode(ur,"utf-8");            giteggur giteggur = jsonutil.tobean(urstr, giteggur.class);            return giteggur;        } catch (unsupportedencodingexception e) {            e.printstacktrace();            return null;        }    }    /**     * 获取租户id     *     * @return tenantid     */    public static string gettenantid() {        httprvletrequest request = giteggwebutils.getrequest();        if (request == null) {            return null;        }        try {            string tenantid = request.getheader(authconstant.tenant_id);            string ur = request.getheader(authconstant.header_ur);            //如果请求头中的tenantid为空,那么尝试是否能够从登陆用户中去获取租户id            if (stringutils.impty(tenantid) && !stringutils.impty(ur))            {                string urstr = urldecoder.decode(ur,"utf-8");                giteggur giteggur = jsonutil.tobean(urstr, giteggur.class);                if (null != giteggur)                {                    tenantid = giteggur.gettenantid();                }            }            return tenantid;        } catch (unsupportedencodingexception e) {            e.printstacktrace();            return null;        }    }}

5、gitegg-cloud工程中gitegg-gateway子工程的authglobalfilter增加设置tenantid的过滤方法

  string tenantid = exchange.getrequest().getheaders().getfirst(authconstan玉不琢不成器故事t.tenant_id);        string token = exchange.getrequest().getheaders().getfirst(authconstant.jwt_token_header);        if (strutil.impty(tenantid) && strutil.impty(token)) {            return chain.filter(exchange);        }        map<string, string=""> addheaders = new hashmap<>();        // 如果系统配置已开启租户模式,设置tenantid        if (enable && strutil.impty(tenantid)) {            addheaders.put(authconstant.tenant_id, tenantid);        }

6、以上为后台的多租户功能集成步骤,在实际项目开发过程中,我们需要考虑到前端页面在租户信息上的配置,实现思路,不用的租户拥有不同的域名,前端页面根据当前域名获取到对应的租户信息,并在公共请求方法设置tenantid参数,保证每次请求能够携带租户信息。

// request interceptorrequest.interceptors.request.u(config => {  const token = storage.ge什么是高等教育t(access_token)  // 如果 token 存在  // 让每个请求携带自定义 token 请根据实际情况自行修改  if (token) {    config.headers['authorization'] = token  }  config.headers['tenantid'] = process.env.vue_app_tenant_id  return config}, errorhandler)

源码地址:

gitee: https://gitee.com/wmz1930/gitegg

github: https://github.com/wmz1930/gitegg

到此这篇关于基于mybatisplus插件tenantlineinnerinterceptor实现多租户功能的文章就介绍到这了,更多相关mybatisplus多租户插件内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-03 23:03:00,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/adeb84bc2e528e4a375a11a4804d032c.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:基于MybatisPlus插件TenantLineInnerInterceptor实现多租户功能.doc

本文 PDF 下载地址:基于MybatisPlus插件TenantLineInnerInterceptor实现多租户功能.pdf

标签:租户   插件   信息   方法
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图