mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 02:08:43 +08:00 
			
		
		
		
	feat: find_in_set函数的跨数据库实现
This commit is contained in:
		| @@ -0,0 +1,50 @@ | |||||||
|  | package cn.iocoder.yudao.framework.mybatis.core.enums; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import com.baomidou.mybatisplus.annotation.DbType; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Getter; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Optional; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * find_in_set函数的跨数据库实现 | ||||||
|  |  * | ||||||
|  |  * @author dhb52 | ||||||
|  |  */ | ||||||
|  | @Getter | ||||||
|  | @AllArgsConstructor | ||||||
|  | public enum FindInSetEnum { | ||||||
|  |  | ||||||
|  |     // FIND_IN_SET: MySQL 类型 | ||||||
|  |     MYSQL("FIND_IN_SET('#{value}', #{column}) <> 0", DbType.MYSQL), | ||||||
|  |     DM("FIND_IN_SET('#{value}', #{column}) <> 0", DbType.DM), | ||||||
|  |  | ||||||
|  |     // INSTR: Oracle 类型 | ||||||
|  |     ORACLE("INSTR(','||#{column}||',' , ',#{value},') <> 0", DbType.ORACLE), | ||||||
|  |  | ||||||
|  |     // CHARINDEX: SQLServer | ||||||
|  |     SQLSERVER("CHARINDEX(',' + #{value} + ',', ',' + #{column} + ',')", DbType.SQL_SERVER), | ||||||
|  |  | ||||||
|  |     // POSITION: PostgreSQL 类型 | ||||||
|  |     POSTGRE_SQL("POSITION('#{value}' IN #{column})", DbType.POSTGRE_SQL), | ||||||
|  |     KINGBASE_ES("POSITION('#{value}' IN #{column})", DbType.KINGBASE_ES), | ||||||
|  |  | ||||||
|  |     // LOCATE: 其他 | ||||||
|  |     H2("LOCATE('#{value}' IN #{column})", DbType.H2), | ||||||
|  |     ; | ||||||
|  |  | ||||||
|  |     public static final Map<DbType, String> MAPS = Arrays.stream(values()) | ||||||
|  |             .collect(Collectors.toMap(FindInSetEnum::getDbType, FindInSetEnum::getSqlTemplate)); | ||||||
|  |  | ||||||
|  |     private String sqlTemplate; | ||||||
|  |     private DbType dbType; | ||||||
|  |  | ||||||
|  |     public static String getTemplate(DbType dbType) { | ||||||
|  |         return Optional.of(MAPS.get(dbType)) | ||||||
|  |                 .orElseThrow(() -> new IllegalArgumentException("FIND_IN_SET not supported")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | package cn.iocoder.yudao.framework.mybatis.core.enums; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
|  | import com.baomidou.mybatisplus.annotation.DbType; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Getter; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 数据库产品名 => mp DbType 的映射关系 | ||||||
|  |  * | ||||||
|  |  * @author dhb52 | ||||||
|  |  */ | ||||||
|  | @Getter | ||||||
|  | @AllArgsConstructor | ||||||
|  | public enum NameToTypeEnum { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * MySQL | ||||||
|  |      */ | ||||||
|  |     MY_SQL("MySQL", DbType.MYSQL), | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Oracle | ||||||
|  |      */ | ||||||
|  |     ORACLE("Oracle", DbType.ORACLE), | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * PostgreSQL | ||||||
|  |      */ | ||||||
|  |     POSTGRE_SQL("PostgreSQL", DbType.POSTGRE_SQL), | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * SQL Server | ||||||
|  |      */ | ||||||
|  |     SQL_SERVER("Microsoft SQL Server", DbType.SQL_SERVER), | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 达梦 | ||||||
|  |      */ | ||||||
|  |     DM("DM DBMS", DbType.DM), | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 人大金仓 | ||||||
|  |      */ | ||||||
|  |     KINGBASE_ES("KingbaseES", DbType.KINGBASE_ES), | ||||||
|  |  | ||||||
|  |     // 华为openGauss ProductName 与 PostgreSQL相同 | ||||||
|  |     ; | ||||||
|  |  | ||||||
|  |     private final String name; | ||||||
|  |     private final DbType type; | ||||||
|  |  | ||||||
|  |     public static final Map<String, DbType> MAPS = Arrays.stream(values()) | ||||||
|  |             .collect(Collectors.toMap(NameToTypeEnum::getName, NameToTypeEnum::getType)); | ||||||
|  |  | ||||||
|  |     public static DbType find(String databaseProductName) { | ||||||
|  |         if (StrUtil.isBlank(databaseProductName)) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         return MAPS.get(databaseProductName); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,9 +1,15 @@ | |||||||
| package cn.iocoder.yudao.framework.mybatis.core.util; | package cn.iocoder.yudao.framework.mybatis.core.util; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.util.spring.SpringUtils; | ||||||
|  | import cn.iocoder.yudao.framework.mybatis.core.enums.NameToTypeEnum; | ||||||
|  | import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; | ||||||
| import com.baomidou.mybatisplus.annotation.DbType; | import com.baomidou.mybatisplus.annotation.DbType; | ||||||
|  |  | ||||||
|  | import javax.sql.DataSource; | ||||||
| import java.sql.Connection; | import java.sql.Connection; | ||||||
|  | import java.sql.DatabaseMetaData; | ||||||
| import java.sql.DriverManager; | import java.sql.DriverManager; | ||||||
|  | import java.sql.SQLException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * JDBC 工具类 |  * JDBC 工具类 | ||||||
| @@ -38,4 +44,22 @@ public class JdbcUtils { | |||||||
|         return com.baomidou.mybatisplus.extension.toolkit.JdbcUtils.getDbType(url); |         return com.baomidou.mybatisplus.extension.toolkit.JdbcUtils.getDbType(url); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 通过当前数据库连接获得对应的 DB 类型 | ||||||
|  |      * | ||||||
|  |      * @return DB 类型 | ||||||
|  |      */ | ||||||
|  |     public static DbType getDbType() { | ||||||
|  |         DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtils.getBean(DynamicRoutingDataSource.class); | ||||||
|  |         DataSource dataSource = dynamicRoutingDataSource.determineDataSource(); | ||||||
|  |         try (Connection conn = dataSource.getConnection()) { | ||||||
|  |             DatabaseMetaData metaData = conn.getMetaData(); | ||||||
|  |             String databaseProductName = metaData.getDatabaseProductName(); | ||||||
|  |             DbType dbType = NameToTypeEnum.find(databaseProductName); | ||||||
|  |             return dbType; | ||||||
|  |         } catch (SQLException e) { | ||||||
|  |             throw new IllegalArgumentException(e.getMessage()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,11 @@ | |||||||
| package cn.iocoder.yudao.framework.mybatis.core.util; | package cn.iocoder.yudao.framework.mybatis.core.util; | ||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollectionUtil; | import cn.hutool.core.collection.CollectionUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.SortingField; | import cn.iocoder.yudao.framework.common.pojo.SortingField; | ||||||
|  | import cn.iocoder.yudao.framework.mybatis.core.enums.FindInSetEnum; | ||||||
|  | import com.baomidou.mybatisplus.annotation.DbType; | ||||||
| import com.baomidou.mybatisplus.core.metadata.OrderItem; | import com.baomidou.mybatisplus.core.metadata.OrderItem; | ||||||
| import com.baomidou.mybatisplus.core.toolkit.StringPool; | import com.baomidou.mybatisplus.core.toolkit.StringPool; | ||||||
| import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; | ||||||
| @@ -34,7 +37,7 @@ public class MyBatisUtils { | |||||||
|         // 排序字段 |         // 排序字段 | ||||||
|         if (!CollectionUtil.isEmpty(sortingFields)) { |         if (!CollectionUtil.isEmpty(sortingFields)) { | ||||||
|             page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ? |             page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ? | ||||||
|                     OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField())) |                             OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField())) | ||||||
|                     .collect(Collectors.toList())); |                     .collect(Collectors.toList())); | ||||||
|         } |         } | ||||||
|         return page; |         return page; | ||||||
| @@ -56,7 +59,7 @@ public class MyBatisUtils { | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 获得 Table 对应的表名 |      * 获得 Table 对应的表名 | ||||||
|      * |      * <p> | ||||||
|      * 兼容 MySQL 转义表名 `t_xxx` |      * 兼容 MySQL 转义表名 `t_xxx` | ||||||
|      * |      * | ||||||
|      * @param table 表 |      * @param table 表 | ||||||
| @@ -85,4 +88,18 @@ public class MyBatisUtils { | |||||||
|         return new Column(tableName + StringPool.DOT + column); |         return new Column(tableName + StringPool.DOT + column); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 跨数据库的 find_in_set 实现 | ||||||
|  |      * | ||||||
|  |      * @param column 字段名称 | ||||||
|  |      * @param value  查询值(不带单引号) | ||||||
|  |      * @return sql | ||||||
|  |      */ | ||||||
|  |     public static String findInSet(String column, Object value) { | ||||||
|  |         // 这里不用SqlConstants.DB_TYPE,因为它是使用 primary 数据源的 url 推断出来的类型 | ||||||
|  |         DbType dbType = JdbcUtils.getDbType(); | ||||||
|  |         return FindInSetEnum.getTemplate(dbType) | ||||||
|  |                 .replace("#{column}", column) | ||||||
|  |                 .replace("#{value}", StrUtil.toString(value)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 dhb52
					dhb52