做网站和app需要多久,电子商务网站建设的方法有哪些,公众号怎么制作文章,单页网站赚钱前言
多租户技术#xff08;multi-tenancy technology#xff09;是一种软件架构技术#xff0c;它允许在单个系统实例上为多个用户或组织提供服务#xff0c;同时确保这些用户之间数据的隔离性。在多租户架构中#xff0c;每个租户#xff08;可以是个人用户、企业、组…前言
多租户技术multi-tenancy technology是一种软件架构技术它允许在单个系统实例上为多个用户或组织提供服务同时确保这些用户之间数据的隔离性。在多租户架构中每个租户可以是个人用户、企业、组织等共享相同的应用程序实例、硬件资源和基础设施但数据和配置是相互隔离的每个租户只能访问自己的数据和配置互不干扰。
功能描述
基于字段tenant_id数据隔离租户排除特殊表排除特殊查询异步支持
代码实现
依赖引入
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.3.2/version
/dependencydependencygroupIdcom.github.jsqlparser/groupIdartifactIdjsqlparser/artifactIdversion3.1/version
/dependencyyml配置
# mybatis-plus配置
mybatis-plus:# 启动检查MyBatis配置文件check-config-location: false# MyBatis配置文件位置config-location:# MyBaits别名包扫描路径type-aliases-package: com.qiangesoft.tenantid.entity# Mapper所对应的XML文件位置 默认【classpath*:/mapper/**/*.xml】mapper-locations: classpath*:/mapper/*Mapper.xml# TypeHandler扫描路径type-handlers-package:configuration:# 日志打印log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 是否开启自动驼峰命名规则map-underscore-to-camel-case: true# 开启Mybatis二级缓存默认为truecache-enabled: trueglobal-config:# 控制台mybatis-plus的logobanner: truedb-config:# 全局默认主键类型id-type: auto# 逻辑删除配置logic-delete-field: deletedlogic-delete-value: 1logic-not-delete-value: 0配置类
package com.qiangesoft.tenantid.config;import com.baomidou.mybatisplus.core.parser.ISqlParser;
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.StringValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** mybatis-plus配置** author qiangesoft* date 2024-04-11*/
Configuration
public class MybatisPlusConfig {Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor new PaginationInterceptor();ListISqlParser sqlParserList new ArrayList();TenantSqlParser tenantSqlParser new TenantSqlParser();tenantSqlParser.setTenantHandler(new TenantHandler() {Overridepublic Expression getTenantId(boolean select) {ServletRequestAttributes attributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request attributes.getRequest();String tenantId request.getHeader(tenantId);return new StringValue(tenantId);}Overridepublic String getTenantIdColumn() {return tenant_id;}/*** 整张表租户过滤排除* param tableName* return*/Overridepublic boolean doTableFilter(String tableName) {ListString ignoreTables Arrays.asList(sys_demo);return ignoreTables.stream().anyMatch(e - e.equalsIgnoreCase(tableName));}});sqlParserList.add(tenantSqlParser);paginationInterceptor.setSqlParserList(sqlParserList);return paginationInterceptor;}}
排除特殊查询
SqlParser(filter true)只能作用于mapper层
package com.qiangesoft.tenantid.mapper;import com.baomidou.mybatisplus.annotation.SqlParser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qiangesoft.tenantid.entity.SysDept;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** p* 部门信息 Mapper 接口* /p** author qiangesoft* since 2024-04-11*/
public interface SysDeptMapper extends BaseMapperSysDept {/*** 不进行租户过滤** param parentId* return*/SqlParser(filter true)ListSysDept listByParam(Param(parentId) Long parentId);}
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.qiangesoft.tenantid.mapper.SysDeptMapperselect idlistByParam resultTypesysDeptselect *from sys_deptwhere parent_id #{parentId}/select/mapper
package com.qiangesoft.tenantid.controller;import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiangesoft.tenantid.entity.SysDept;
import com.qiangesoft.tenantid.entity.SysUser;
import com.qiangesoft.tenantid.service.ISysDeptService;
import com.qiangesoft.tenantid.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** p* 用户信息 前端控制器* /p** author qiangesoft* since 2024-04-11*/
Slf4j
RestController
RequestMapping(/sys-user)
public class SysUserController {Autowiredprivate ISysUserService sysUserService;Autowiredprivate ISysDeptService sysDeptService;GetMapping(/list)public ListSysUser list() {LambdaQueryWrapperSysUser queryWrapper new LambdaQueryWrapper();queryWrapper.orderByDesc(SysUser::getCreateTime);ListSysUser sysUserList sysUserService.list(queryWrapper);log.info(JSON.toJSONString(sysUserList));ListSysDept sysDeptList sysDeptService.listByParam(1L);log.info(JSON.toJSONString(sysDeptList));return sysUserList;}}package com.qiangesoft.tenantid.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.qiangesoft.tenantid.entity.SysDept;import java.util.List;/*** p* 部门信息 服务类* /p** author qiangesoft* since 2024-04-11*/
public interface ISysDeptService extends IServiceSysDept {/*** 查询部门** param parentId* return*/ListSysDept listByParam(Long parentId);} 异步支持
package com.qiangesoft.tenantid.controller;import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiangesoft.tenantid.entity.SysDept;
import com.qiangesoft.tenantid.entity.SysUser;
import com.qiangesoft.tenantid.service.ISysDeptService;
import com.qiangesoft.tenantid.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;/*** p* 用户信息 前端控制器* /p** author qiangesoft* since 2024-04-11*/
Slf4j
RestController
RequestMapping(/sys-user)
public class SysUserController {Autowiredprivate ISysUserService sysUserService;Autowiredprivate ISysDeptService sysDeptService;GetMapping(/sync)public ListSysDept sync() throws ExecutionException, InterruptedException {LambdaQueryWrapperSysUser queryWrapper new LambdaQueryWrapper();queryWrapper.orderByDesc(SysUser::getCreateTime);ListSysUser sysUserList sysUserService.list(queryWrapper);log.info(JSON.toJSONString(sysUserList));// 异步查询部门ServletRequestAttributes sra (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();Callable getUser () - {RequestContextHolder.setRequestAttributes(sra, true);ListSysDept sysDeptList sysDeptService.list();log.info(JSON.toJSONString(sysDeptList));return sysUserList;};FutureTaskListSysDept future new FutureTask(getUser);new Thread(future).start();return future.get();}}请求调用
请求头添加tenantId