feat(多数据源脚本): 达梦、SQL server、postgres

This commit is contained in:
gx_ma
2025-04-22 10:03:31 +08:00
parent ff51ea78af
commit 54f2487330
13 changed files with 17310 additions and 4 deletions

View File

@@ -9,7 +9,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
*
* @author ruoyi
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@SpringBootApplication
public class FastBeeApplication
{
public static void main(String[] args)

View File

@@ -0,0 +1,64 @@
package com.fastbee.common.mabatis.enums;
import com.fastbee.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 数据库类型
*
* @author Lion Li
*/
@Getter
@AllArgsConstructor
public enum DataBaseType {
/**
* MySQL
*/
MY_SQL("MySQL"),
/**
* Oracle
*/
ORACLE("Oracle"),
/**
* PostgreSQL
*/
POSTGRE_SQL("PostgreSQL"),
/**
* SQL Server
*/
SQL_SERVER("Microsoft SQL Server"),
/**
* 达梦
*/
DM("DM DBMS");
/**
* 数据库类型
*/
private final String type;
/**
* 根据数据库产品名称查找对应的数据库类型
*
* @param databaseProductName 数据库产品名称
* @return 对应的数据库类型枚举值,如果未找到则返回 null
*/
public static DataBaseType find(String databaseProductName) {
if (StringUtils.isBlank(databaseProductName)) {
return null;
}
for (DataBaseType type : values()) {
if (type.getType().equals(databaseProductName)) {
return type;
}
}
return null;
}
}

View File

@@ -59,6 +59,13 @@
<artifactId>oshi-core</artifactId>
</dependency>
<!-- 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-datasource.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,69 @@
package com.fastbee.framework.config;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class DataSourceConfig {
private final DynamicDataSourceProperties properties;
private final DefaultDataSourceCreator dataSourceCreator;
private final DataSource shardingSphereDataSource;
public DataSourceConfig(DynamicDataSourceProperties properties,
DefaultDataSourceCreator dataSourceCreator,
@Lazy
@Qualifier("shardingSphereDataSource") DataSource shardingSphereDataSource) {
this.properties = properties;
this.dataSourceCreator = dataSourceCreator;
this.shardingSphereDataSource = shardingSphereDataSource;
}
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
return new AbstractDataSourceProvider(dataSourceCreator) {
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSource> dataSourceMap = new HashMap<>();
// 把 shardingSphereDataSource 加入多数据源,到时候使用的时候就可以 `@DS("shardingSphere")`
if(null != shardingSphereDataSource) {
dataSourceMap.put("shardingSphere", shardingSphereDataSource);
}
return dataSourceMap;
}
};
}
@Primary
@Bean
public DataSource dataSource(List<DynamicDataSourceProvider> providers) {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource(providers);
dataSource.setPrimary(properties.getPrimary());
dataSource.setStrict(properties.getStrict());
dataSource.setStrategy(properties.getStrategy());
dataSource.setP6spy(properties.getP6spy());
dataSource.setSeata(properties.getSeata());
return dataSource;
}
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}

View File

@@ -0,0 +1,164 @@
package com.fastbee.framework.mybatis.helper;
import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.mabatis.enums.DataBaseType;
import com.fastbee.common.utils.spring.SpringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 数据库助手
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DataBaseHelper {
private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class);
public static final String DEFAULT_DATASOURCE_NAME = "master";
/**
* 获取当前数据库类型
*/
public static DataBaseType getDataBaseType(String dataName) {
DataSource dataSource = DS.getDataSources().get(dataName);
try (Connection conn = dataSource.getConnection()) {
DatabaseMetaData metaData = conn.getMetaData();
String databaseProductName = metaData.getDatabaseProductName();
return DataBaseType.find(databaseProductName);
} catch (SQLException e) {
throw new ServiceException(e.getMessage());
}
}
public static boolean isMySql() {
return DataBaseType.MY_SQL == getDataBaseType(DEFAULT_DATASOURCE_NAME);
}
public static boolean isOracle() {
return DataBaseType.ORACLE == getDataBaseType(DEFAULT_DATASOURCE_NAME);
}
public static boolean isPostgerSql() {
return DataBaseType.POSTGRE_SQL == getDataBaseType(DEFAULT_DATASOURCE_NAME);
}
public static boolean isSqlServer() {
return DataBaseType.SQL_SERVER == getDataBaseType(DEFAULT_DATASOURCE_NAME);
}
public static boolean isDm() {
return DataBaseType.DM == getDataBaseType(DEFAULT_DATASOURCE_NAME);
}
public static boolean isMySql(String dataName) {
return DataBaseType.MY_SQL == getDataBaseType(dataName);
}
public static boolean isOracle(String dataName) {
return DataBaseType.ORACLE == getDataBaseType(dataName);
}
public static boolean isPostgerSql(String dataName) {
return DataBaseType.POSTGRE_SQL == getDataBaseType(dataName);
}
public static boolean isSqlServer(String dataName) {
return DataBaseType.SQL_SERVER == getDataBaseType(dataName);
}
public static boolean isDm(String dataName) {
return DataBaseType.DM == getDataBaseType(dataName);
}
public static String findInSet(Object var1, String var2) {
DataBaseType dataBasyType = getDataBaseType(DEFAULT_DATASOURCE_NAME);
String var = Convert.toStr(var1);
if (dataBasyType == DataBaseType.SQL_SERVER) {
// charindex(',100,' , ',0,100,101,') <> 0
return String.format("charindex(',%s,' , ','+%s+',') <> 0", var, var2);
} else if (dataBasyType == DataBaseType.POSTGRE_SQL) {
// (select strpos(',0,100,101,' , ',100,')) <> 0
return String.format("(select strpos(','||%s||',' , ',%s,')) <> 0", var2, var);
} else if (dataBasyType == DataBaseType.ORACLE || dataBasyType == DataBaseType.DM) {
// instr(',0,100,101,' , ',100,') <> 0
return String.format("instr(','||%s||',' , ',%s,') <> 0", var2, var);
}
// find_in_set(100 , '0,100,101')
return String.format("find_in_set(%s , %s) <> 0", var, var2);
}
public static String findInSetColumn(String var1, String var2) {
DataBaseType dataBasyType = getDataBaseType(DEFAULT_DATASOURCE_NAME);
String var = Convert.toStr(var1);
if (dataBasyType == DataBaseType.SQL_SERVER) {
// charindex(','+de.dept_id+',' , ',0,100,101,') <> 0
return String.format("charindex(',' + %s + ',' , ',' + %s + ',') <> 0", var, var2);
} else if (dataBasyType == DataBaseType.POSTGRE_SQL) {
// (select strpos(',0,100,101,' , ',' || de.dept_id || ',')) <> 0
return String.format("(select strpos(','||%s||',' , ','|| %s ||',')) <> 0", var2, var);
} else if (dataBasyType == DataBaseType.ORACLE|| dataBasyType == DataBaseType.DM) {
// instr(',0,100,101,' , ','||de.dept_id||',') <> 0
return String.format("instr(','||%s||',' , ','||%s||',') <> 0", var2, var);
}
// find_in_set(de.dept_id , '0,100,101')
return String.format("find_in_set(%s , '%s') <> 0", var, var2);
}
/**
* 获取当前加载的数据库名
*/
public static List<String> getDataSourceNameList() {
return new ArrayList<>(DS.getDataSources().keySet());
}
public static String getDeptCondition(Long deptId) {
if (deptId == null || deptId == 0) {
// 无效条件,确保查询不会返回结果
return "1=1";
}
if (isPostgerSql()) {
return "SELECT u.user_id FROM sys_user u WHERE u.dept_id IN (SELECT dept_id FROM sys_dept WHERE " + deptId + "::text = ANY(string_to_array(ancestors, ',')) OR dept_id = " + deptId + ")";
} else if (isSqlServer()) {
return "SELECT u.user_id FROM sys_user u WHERE u.dept_id IN (SELECT dept_id FROM sys_dept WHERE CHARINDEX(',' + CAST(" + deptId + " AS VARCHAR) + ',', ',' + ancestors + ',') > 0 OR dept_id = " + deptId + ")";
} else if (isOracle()) {
return "SELECT u.user_id FROM sys_user u WHERE u.dept_id IN (SELECT dept_id FROM sys_dept WHERE INSTR(',' || ancestors || ',', ',' || " + deptId + " || ',') > 0 OR dept_id = " + deptId + ")";
} else if (isDm()) {
return "SELECT u.user_id FROM sys_user u WHERE u.dept_id IN (SELECT dept_id FROM sys_dept WHERE INSTR(',' || ancestors || ',', ',' || " + deptId + " || ',') > 0 OR dept_id = " + deptId + ")";
} else if (isMySql()) {
return "SELECT u.user_id FROM sys_user u WHERE u.dept_id IN (SELECT dept_id FROM sys_dept WHERE FIND_IN_SET(" + deptId + ", ancestors) > 0 OR dept_id = " + deptId + ")";
} else {
throw new UnsupportedOperationException("Unsupported database type");
}
}
public static String checkTime(Integer timeout) {
if (timeout == null || timeout == 0) {
// 无效条件,确保查询不会返回结果
return "";
}
if (isPostgerSql()) {
return "CURRENT_TIMESTAMP > last_connect_time + interval '1 seconds' * " + timeout;
} else if (isSqlServer()) {
return "CURRENT_TIMESTAMP > DATEADD(SECOND, " + timeout + " last_connect_time)";
} else if (isOracle()) {
return "CURRENT_TIMESTAMP > last_connect_time + (" + timeout + " / 86400)";
} else if (isDm()) {
return "CURRENT_TIMESTAMP > DATEADD(SECOND, " + timeout + ", last_connect_time)";
} else if (isMySql()) {
return "CURRENT_TIMESTAMP > DATE_ADD(last_connect_time, INTERVAL " + timeout + " SECOND)";
} else {
throw new UnsupportedOperationException("Unsupported database type");
}
}
}

View File

@@ -2,6 +2,7 @@ package com.fastbee.data.service.impl;
import com.fastbee.base.session.Session;
import com.fastbee.common.enums.DeviceStatus;
import com.fastbee.framework.mybatis.helper.DataBaseHelper;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.model.DeviceStatusVO;
import com.fastbee.iot.service.IDeviceService;
@@ -42,7 +43,8 @@ public class DeviceJob {
private Boolean enabled;
public void updateSipDeviceOnlineStatus(Integer timeout) {
List<SipDevice> devs = sipDeviceMapper.selectOfflineSipDevice(timeout);
String checkTimeCondition = DataBaseHelper.checkTime(timeout);
List<SipDevice> devs = sipDeviceMapper.selectOfflineSipDevice(checkTimeCondition);
devs.forEach(item -> {
if (!Objects.equals(item.getDeviceSipId(), "")) {
//更新iot设备状态

View File

@@ -31,7 +31,7 @@ public interface SipDeviceMapper
* @return 监控设备集合
*/
public List<SipDevice> selectSipDeviceList(SipDevice sipDevice);
public List<SipDevice> selectOfflineSipDevice(Integer timeout);
public List<SipDevice> selectOfflineSipDevice(String checkTimeCondition);
/**
* 新增监控设备

View File

@@ -196,7 +196,7 @@
<select id="selectOfflineSipDevice" parameterType="Integer" resultMap="SipDeviceResult">
<include refid="selectSipDeviceVo"/>
where NOW() > DATE_ADD(lastconnecttime, INTERVAL #{timeout} SECOND )
${checkTimeCondition}
</select>
<select id="selectSipDeviceBySipId" parameterType="String" resultMap="SipDeviceResult">

View File

@@ -120,6 +120,13 @@
<artifactId>fastbee-ruleEngine</artifactId>
</dependency>
<!--引入DM8驱动-->
<dependency>
<groupId>com.dameng</groupId>
<artifactId>Dm8JdbcDriver18</artifactId>
<version>8.1.1.49</version>
</dependency>
</dependencies>
</project>

View File

@@ -23,6 +23,12 @@
<artifactId>fastbee-common</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring</artifactId>
<version>${dynamic-datasource.version}</version>
</dependency>
</dependencies>
</project>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long