first commit

This commit is contained in:
2023-05-22 20:14:18 +08:00
parent 3baba77120
commit f5aa6b2f69
18 changed files with 158 additions and 167 deletions

View File

@ -1,8 +1,5 @@
package com.qiaoba.common.base.context;
import java.util.HashMap;
import java.util.Map;
/**
* 全局上下文对象
*
@ -12,31 +9,74 @@ import java.util.Map;
*/
public class BaseContext {
private static final String DATABASE_TYPE_MAP_KEY = "databaseType";
/**
* 数据库类型
*/
private static final ThreadLocal<String> DATABASE_TYPE_HOLDER = new ThreadLocal<>();
private static final ThreadLocal<Map<String, Object>> CONTEXT_HOLDER = new ThreadLocal<>();
/**
* 租户ID
*/
private static final ThreadLocal<String> TENANT_ID_HOLDER = new ThreadLocal<>();
/**
* 数据源
*/
private static final ThreadLocal<String> DATASOURCE_HOLDER = new ThreadLocal<>();
/**
* 获取上下文中数据库类型
*/
public static String getDatabaseType() {
return DATABASE_TYPE_HOLDER.get();
}
/**
* 设置上下文中数据库类型
*/
public static void setDatabaseType(String type) {
DATABASE_TYPE_HOLDER.set(type);
}
/**
* 获取上下文中租户ID
*/
public static String getTenantId() {
return TENANT_ID_HOLDER.get();
}
/**
* 设置上下文中租户ID
*/
public static void setTenantId(String tenantId) {
TENANT_ID_HOLDER.set(tenantId);
}
/**
* 获取上下文中的数据源
*/
public String getDatabaseType() {
return CONTEXT_HOLDER.get().get(DATABASE_TYPE_MAP_KEY).toString();
public static String getDataSource() {
return DATASOURCE_HOLDER.get();
}
/**
* 设置上下文中的数据源
*/
public void setDatabaseType(String type) {
Map<String, Object> map = new HashMap<>(1);
map.put(DATABASE_TYPE_MAP_KEY, type);
CONTEXT_HOLDER.set(map);
public static void setDataSource(String dataSource) {
DATASOURCE_HOLDER.set(dataSource);
}
/**
* 清除上下文中的数据源
* 清除所有的ThreadLocal
*/
public void clearDataSource() {
CONTEXT_HOLDER.remove();
public static void clearAllHolder() {
// 清除上下文中数据源
DATASOURCE_HOLDER.remove();
// 清除上下文中租户ID
TENANT_ID_HOLDER.remove();
// 清除上下文中数据库类型
DATABASE_TYPE_HOLDER.remove();
}

View File

@ -1,4 +1,4 @@
package com.qiaoba.common.database.enums;
package com.qiaoba.common.base.enums;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
@ -48,4 +48,5 @@ public enum DataBaseTypeEnum {
}
return null;
}
}

View File

@ -1,16 +1,10 @@
package com.qiaoba.common.database.utils;
package com.qiaoba.common.base.utils;
import cn.hutool.core.convert.Convert;
import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
import com.qiaoba.common.database.enums.DataBaseTypeEnum;
import com.qiaoba.common.base.context.BaseContext;
import com.qiaoba.common.base.enums.DataBaseTypeEnum;
import lombok.extern.slf4j.Slf4j;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
/**
* 数据库工具类
*
@ -21,23 +15,15 @@ import java.sql.SQLException;
@Slf4j
public class DatabaseUtil {
/**
* 获取当前数据库类型
* 根据数据库类型处理find_in_set函数
*
* @param var1 参数1
* @param var2 参数2
* @return 处理后的sql
*/
public static DataBaseTypeEnum getDataBaseType() {
DataSource dataSource = (DataSource) DynamicDataSourceConfig.DATA_SOURCE_MAP.get("");
try (Connection conn = dataSource.getConnection()) {
DatabaseMetaData metaData = conn.getMetaData();
String databaseProductName = metaData.getDatabaseProductName();
return DataBaseTypeEnum.find(databaseProductName);
} catch (SQLException e) {
throw new ServiceException(e.getMessage());
}
}
public static String handleFindInSet(Object var1, String var2) {
DataBaseTypeEnum dataBaseType = getDataBaseType();
DataBaseTypeEnum dataBaseType = DataBaseTypeEnum.find(BaseContext.getDatabaseType());
String var = Convert.toStr(var1);
if (dataBaseType == DataBaseTypeEnum.SQL_SERVER) {
// charindex(',100,' , ',0,100,101,') <> 0

View File

@ -1,30 +0,0 @@
package com.qiaoba.common.base.utils;
/**
* 租户工具类
*
* @author ailanyin
* @version 1.0
* @since 2023/5/9 12:57
*/
public class TenantUtil {
private static final ThreadLocal<String> TENANT_ID_HOLDER = new ThreadLocal<>();
/**
* 获取登录用户的租户ID
*
* @return username
*/
public static String getTenantId() {
return TENANT_ID_HOLDER.get();
}
public static void clearTenantId() {
TENANT_ID_HOLDER.remove();
}
public static void setTenantId(String tenantId) {
TENANT_ID_HOLDER.set(tenantId);
}
}

View File

@ -1,5 +1,6 @@
package com.qiaoba.common.database.config;
import com.qiaoba.common.base.context.BaseContext;
import com.qiaoba.common.database.constants.DynamicDatasourceConstant;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
@ -15,9 +16,6 @@ import java.util.Map;
public class DynamicDataSourceContext extends AbstractRoutingDataSource {
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
/**
* 设置默认数据源、全部数据源,及刷新
*/
@ -33,7 +31,7 @@ public class DynamicDataSourceContext extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
//获取当前指定的数据源
return getDataSource();
return BaseContext.getDataSource();
}
@ -41,24 +39,4 @@ public class DynamicDataSourceContext extends AbstractRoutingDataSource {
public void afterPropertiesSet() {
}
/**
* 获取上下文中的数据源
*/
public String getDataSource() {
return CONTEXT_HOLDER.get();
}
/**
* 设置上下文中的数据源
*/
public void setDataSource(String dataSource) {
CONTEXT_HOLDER.set(dataSource);
}
/**
* 清除上下文中的数据源
*/
public void clearDataSource() {
CONTEXT_HOLDER.remove();
}
}

View File

@ -4,7 +4,7 @@ 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 com.qiaoba.common.base.utils.TenantUtil;
import com.qiaoba.common.base.context.BaseContext;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.context.annotation.Bean;
@ -26,7 +26,7 @@ public class MybatisPlusConfig {
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
@Override
public Expression getTenantId() {
return new StringValue(TenantUtil.getTenantId());
return new StringValue(BaseContext.getTenantId());
}
@Override

View File

@ -1,9 +1,8 @@
package com.qiaoba.common.database.filters;
import com.qiaoba.common.base.utils.TenantUtil;
import com.qiaoba.common.base.context.BaseContext;
import com.qiaoba.common.database.config.DynamicDataSourceContext;
import com.qiaoba.common.database.constants.DynamicDatasourceConstant;
import com.qiaoba.common.database.utils.DatabaseUtil;
import com.qiaoba.common.web.utils.ResponseUtil;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@ -33,14 +32,9 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//设置当前租户对应的数据库
dynamicDataSourceContext.setDataSource(DynamicDatasourceConstant.DEFAULT_MASTER_DATASOURCE_KEY);
// todo
TenantUtil.setTenantId("1");
DatabaseUtil.handleFindInSet();
before();
filterChain.doFilter(request, response);
dynamicDataSourceContext.clearDataSource();
TenantUtil.clearTenantId();
after();
}
private boolean checkTenantInfo(String tenantCode, ServletResponse servletResponse) throws IOException {
@ -49,4 +43,17 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
return false;
}
private void before() {
// todo
//设置当前租户对应的数据源
BaseContext.setDataSource(DynamicDatasourceConstant.DEFAULT_MASTER_DATASOURCE_KEY);
//设置当前租户对应的租户ID
BaseContext.setTenantId("1");
//设置当前租户对应的数据库类型
BaseContext.setDatabaseType("MySQL");
}
private void after() {
BaseContext.clearAllHolder();
}
}

View File

@ -0,0 +1,25 @@
package com.qiaoba.common.database.interceptors;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import java.sql.Connection;
import java.sql.SQLException;
@Slf4j
public class SchemaInterceptor implements InnerInterceptor {
@Override
public void beforePrepare(StatementHandler sh, Connection conn, Integer transactionTimeout) {
String sql = "use `qiaoba-boot`;";
try {
conn.createStatement().execute(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
InnerInterceptor.super.beforePrepare(sh, conn, transactionTimeout);
}
}

View File

@ -1,7 +1,7 @@
package com.qiaoba.common.redis.service.impl;
import com.qiaoba.common.base.utils.TenantUtil;
import com.qiaoba.common.base.context.BaseContext;
import com.qiaoba.common.redis.service.RedisService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
@ -231,7 +231,7 @@ public class RedisServiceImpl implements RedisService {
private String handleKey(String key) {
StringBuilder sb = new StringBuilder();
sb.append("tenant_").append(TenantUtil.getTenantId()).append(":").append(key);
sb.append("tenant_").append(BaseContext.getTenantId()).append(":").append(key);
return sb.toString();
}
}