diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/mabatis/enums/DataBaseType.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/mabatis/enums/DataBaseType.java new file mode 100644 index 00000000..2fef9e70 --- /dev/null +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/mabatis/enums/DataBaseType.java @@ -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; + } +} diff --git a/springboot/fastbee-framework/pom.xml b/springboot/fastbee-framework/pom.xml index f9f2734e..6a9ecba0 100644 --- a/springboot/fastbee-framework/pom.xml +++ b/springboot/fastbee-framework/pom.xml @@ -63,6 +63,13 @@ oshi-core + + + com.baomidou + dynamic-datasource-spring-boot-starter + ${dynamic-datasource.version} + + diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/mybatis/helper/DataBaseHelper.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/mybatis/helper/DataBaseHelper.java new file mode 100644 index 00000000..2299365c --- /dev/null +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/mybatis/helper/DataBaseHelper.java @@ -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 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"); + } + } + +} diff --git a/springboot/fastbee-open-api/src/main/java/com/fastbee/data/service/impl/DeviceJob.java b/springboot/fastbee-open-api/src/main/java/com/fastbee/data/service/impl/DeviceJob.java index 8ae40e5f..7497f5ef 100644 --- a/springboot/fastbee-open-api/src/main/java/com/fastbee/data/service/impl/DeviceJob.java +++ b/springboot/fastbee-open-api/src/main/java/com/fastbee/data/service/impl/DeviceJob.java @@ -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 devs = sipDeviceMapper.selectOfflineSipDevice(timeout); + String checkTimeCondition = DataBaseHelper.checkTime(timeout); + List devs = sipDeviceMapper.selectOfflineSipDevice(checkTimeCondition); devs.forEach(item -> { if (!Objects.equals(item.getDeviceSipId(), "")) { //更新iot设备状态 diff --git a/springboot/fastbee-server/sip-server/src/main/java/com/fastbee/sip/mapper/SipDeviceMapper.java b/springboot/fastbee-server/sip-server/src/main/java/com/fastbee/sip/mapper/SipDeviceMapper.java index d84875f3..8a79b384 100644 --- a/springboot/fastbee-server/sip-server/src/main/java/com/fastbee/sip/mapper/SipDeviceMapper.java +++ b/springboot/fastbee-server/sip-server/src/main/java/com/fastbee/sip/mapper/SipDeviceMapper.java @@ -31,7 +31,7 @@ public interface SipDeviceMapper * @return 监控设备集合 */ public List selectSipDeviceList(SipDevice sipDevice); - public List selectOfflineSipDevice(Integer timeout); + public List selectOfflineSipDevice(String checkTimeCondition); /** * 新增监控设备 diff --git a/springboot/fastbee-server/sip-server/src/main/resources/mapper/SipDeviceMapper.xml b/springboot/fastbee-server/sip-server/src/main/resources/mapper/SipDeviceMapper.xml index 73237e0c..208f1d13 100644 --- a/springboot/fastbee-server/sip-server/src/main/resources/mapper/SipDeviceMapper.xml +++ b/springboot/fastbee-server/sip-server/src/main/resources/mapper/SipDeviceMapper.xml @@ -196,7 +196,7 @@