This commit is contained in:
2023-06-20 17:20:28 +08:00
parent efab939bdf
commit 2ec376f0f8
10 changed files with 292 additions and 255 deletions

View File

@ -3,6 +3,7 @@ package com.qiaoba.common.database.handlers.schema;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.context.BaseContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@ -18,15 +19,19 @@ import java.sql.Statement;
* @since 2023/6/20 9:25
*/
@Component
@Slf4j
public class MysqlSchemaHandler implements SchemaHandler {
@Value("${spring.application.name}")
private String baseDatabase;
private static final String MYSQL_CHANGE_SCHEMA_SQL = "alter session set current_schema = {}";
@Override
public void setSchema(Connection conn) {
// eg: use qiaoba-1;
String sql = StrUtil.format("use `{}-{}`;", baseDatabase, BaseContext.getTenantId());
log.debug("Run MysqlSchemaHandler, Sql: {}", sql);
Statement statement = null;
try {
statement = conn.createStatement();

View File

@ -0,0 +1,35 @@
package com.qiaoba.common.database.handlers.schema;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
/**
* OracleSchemaHandler
*
* @author ailanyin
* @version 1.0
* @since 2023/6/20 9:25
*/
@Component
public class OracleSchemaHandler implements SchemaHandler {
private static final String ORACLE_CHANGE_SCHEMA_SQL = "alter session set current_schema = {};";
@Override
public void setSchema(Connection conn) {
Statement statement = null;
try {
statement = conn.createStatement();
statement.execute(StrUtil.format(ORACLE_CHANGE_SCHEMA_SQL, "ROOT"));
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
IoUtil.close(statement);
}
}
}

View File

@ -3,7 +3,7 @@ package com.qiaoba.common.database.handlers.schema;
import com.qiaoba.common.base.enums.DataBaseEnum;
import com.qiaoba.common.base.exceptions.ServiceException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.Map;
@ -17,21 +17,21 @@ import java.util.concurrent.ConcurrentHashMap;
* @version 1.0
* @since 2023/6/20 9:22
*/
@Component
@Configuration
@RequiredArgsConstructor
public class SchemaHandlerFactory {
private static Map<String, SchemaHandler> handlerMap = new ConcurrentHashMap<>();
private static Map<String, SchemaHandler> HANDLERS = new ConcurrentHashMap<>();
private final MysqlSchemaHandler mysqlSchemaHandler;
@PostConstruct
public void register() {
handlerMap.put(DataBaseEnum.MY_SQL.getType(), mysqlSchemaHandler);
HANDLERS.put(DataBaseEnum.MY_SQL.getType(), mysqlSchemaHandler);
}
public static SchemaHandler getHandler(String name) {
SchemaHandler schemaHandler = handlerMap.get(name);
SchemaHandler schemaHandler = HANDLERS.get(name);
if (Objects.isNull(schemaHandler)) {
throw new ServiceException("Schema处理器工厂异常, 类型:[" + name + "]找不到相对应的解析器");
}

View File

@ -3,6 +3,8 @@ package com.qiaoba.common.database.monitor;
import cn.hutool.core.io.IoUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.qiaoba.common.base.constants.TenantConstant;
import com.qiaoba.common.base.context.BaseContext;
import com.qiaoba.common.base.enums.DataBaseEnum;
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
import com.qiaoba.common.database.entity.DynamicDataSource;
import com.qiaoba.common.database.service.DynamicDatasourceService;
@ -29,8 +31,6 @@ import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class DatasourceConnectionMonitor {
private static final String CHECK_SQL = "SELECT 1";
@Resource
private DynamicDataSourceConfig dynamicDataSourceConfig;
@Resource
@ -60,7 +60,7 @@ public class DatasourceConnectionMonitor {
DruidDataSource dataSource = (DruidDataSource) primary;
try {
Connection connection = dataSource.getConnection();
if (check(connection)) {
if (check(connection, tenantId)) {
// 说明数据源正常
log.trace("租户[{}]-目前主数据源正常, 无需切换数据源", tenantId);
// 主数据 处理任务
@ -89,14 +89,14 @@ public class DatasourceConnectionMonitor {
}, 0, 1000);
}
private Boolean check(Connection conn) {
private Boolean check(Connection conn, String tenantId) {
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
// 允许 2s 延时
stmt.setQueryTimeout(2);
rs = stmt.executeQuery(CHECK_SQL);
rs = stmt.executeQuery(DataBaseEnum.getCheckSql(DynamicDataSourceConfig.TENANT_DATASOURCE_TYPE_MAP.get(tenantId)));
return true;
} catch (Exception e) {
return false;

View File

@ -53,24 +53,4 @@ public class JdbcUtil {
}
}
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = getConnection("oracle.jdbc.OracleDriver", "jdbc:oracle:thin:@//101.34.251.155:1521/ORCL", "ROOT", "root");
statement = connection.createStatement();
statement.executeQuery("alter session set current_schema=ROOT");
resultSet = statement.executeQuery("SELECT * FROM SYS_USER");
while (resultSet.next()) {
System.out.println(resultSet.getString("NICKNAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
IoUtil.close(connection);
IoUtil.close(statement);
IoUtil.close(resultSet);
}
}
}

View File

@ -1,4 +1,6 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qiaoba.common.database.factories.DynamicDataSourceFactory,\
com.qiaoba.common.database.monitor.DatasourceConnectionMonitor,\
com.qiaoba.common.database.handlers.schema.SchemaHandlerFactory,\
com.qiaoba.common.database.handlers.schema.MysqlSchemaHandler,\
com.qiaoba.common.database.config.MybatisPlusConfig