Commit 679d1bbdbdf003abff02f3ec426ac43773acb0f1
1 parent
8c5e7048
feat: 支持神通数据库普通 CRUD 与代码生成
Showing
9 changed files
with
114 additions
and
8 deletions
sql/tools/README.md
| @@ -219,6 +219,44 @@ password: Yudao@2024 | @@ -219,6 +219,44 @@ password: Yudao@2024 | ||
| 219 | 219 | ||
| 220 | > 注意:端口只绑定本机 `127.0.0.1:15432`;`omm` 初始用户不允许远程连接,项目使用 `mogdb` 用户。`jdbc:opengauss:` 按 PostgreSQL 处理序列主键、Quartz 等差异,驱动需要引入到 `yudao-server/pom.xml` 的 `<dependencies>` 中。详见 [《国产信创数据库》](https://doc.iocoder.cn/xinchuang-db/#_11-云和恩墨-mogdb-数据库) 文档。 | 220 | > 注意:端口只绑定本机 `127.0.0.1:15432`;`omm` 初始用户不允许远程连接,项目使用 `mogdb` 用户。`jdbc:opengauss:` 按 PostgreSQL 处理序列主键、Quartz 等差异,驱动需要引入到 `yudao-server/pom.xml` 的 `<dependencies>` 中。详见 [《国产信创数据库》](https://doc.iocoder.cn/xinchuang-db/#_11-云和恩墨-mogdb-数据库) 文档。 |
| 221 | 221 | ||
| 222 | +### 1.13 神通数据库 | ||
| 223 | + | ||
| 224 | +神通数据库需要自行安装,安装介质和授权请通过 [神通官方下载中心](http://shentongdata.com/index.php/download/list-27) 获取。项目复用 `sql/opengauss` 脚本,默认仍然使用 MySQL。 | ||
| 225 | + | ||
| 226 | +① 初始化数据库:创建神通账号时,会自动创建同名的模式,项目的表创建在该模式中(`url` 中的 `currentSchema` 参数不生效)。神通已内置 `dual`,且 `varchar` 最大长度为 8000,所以先在 `sql/tools` 目录下生成临时脚本:只跳过创建 `dual` 表的一段,并将 `varchar(10240)` 改为 `text`,其余 SQL 保持不变: | ||
| 227 | + | ||
| 228 | +```Bash | ||
| 229 | +sed -e '/^-- Table structure for dual$/,/^-- @formatter:on$/d' -e 's/varchar(10240)/text/' ../opengauss/ruoyi-vue-pro.sql > /tmp/ruoyi-vue-pro-shentong.sql | ||
| 230 | +``` | ||
| 231 | + | ||
| 232 | +使用神通的客户端或其它 JDBC 工具,以该账号执行 `/tmp/ruoyi-vue-pro-shentong.sql`。导入完成后,再执行如下 SQL,让 `system_menu` 的主键默认使用 `system_menu_seq` 序列(代码生成的菜单 SQL 与 Oracle、达梦相同,插入菜单时不指定主键): | ||
| 233 | + | ||
| 234 | +```sql | ||
| 235 | +ALTER TABLE system_menu ALTER COLUMN id SET DEFAULT nextval('system_menu_seq'); | ||
| 236 | +``` | ||
| 237 | + | ||
| 238 | +> 注意:神通暂未适配 Quartz,不需要导入 `sql/opengauss/quartz.sql`;`application-local.yaml` 默认排除了 Quartz 的自动配置,保持不变即可。 | ||
| 239 | + | ||
| 240 | +② 项目使用神通 JDBC 驱动(`com.oscar.Driver`),使用序列主键(复用 MyBatis Plus 的 `PostgreKeyGenerator`),分页使用 MyBatis Plus 内置的神通方言。将数据源配置中的地址、账号和密码修改为: | ||
| 241 | + | ||
| 242 | +```yaml | ||
| 243 | +url: jdbc:oscar://127.0.0.1:2003/OSRDB | ||
| 244 | +username: 神通账号 | ||
| 245 | +password: 神通密码 | ||
| 246 | +``` | ||
| 247 | + | ||
| 248 | +驱动需要引入到 `yudao-server/pom.xml` 的 `<dependencies>` 中(`yudao-dependencies`、`yudao-spring-boot-starter-mybatis` 不包含该驱动): | ||
| 249 | + | ||
| 250 | +```xml | ||
| 251 | +<dependency> | ||
| 252 | + <groupId>com.shentongdata</groupId> | ||
| 253 | + <artifactId>oscarJDBC8</artifactId> | ||
| 254 | + <version>4.1.152</version> | ||
| 255 | +</dependency> | ||
| 256 | +``` | ||
| 257 | + | ||
| 258 | +> 注意:该驱动是 Maven 中央仓库上 `com.shentongdata` 发布的版本,不是神通官方下载中心的配套认证版本。项目适配时使用的是神通 7.0.14,其它版本请自行验证。 | ||
| 259 | + | ||
| 222 | ## 1.X 容器的销毁重建 | 260 | ## 1.X 容器的销毁重建 |
| 223 | 261 | ||
| 224 | 开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据 Docker 容器采用数据卷 Volume 挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。 | 262 | 开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据 Docker 容器采用数据卷 Volume 挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。 |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java
| @@ -30,7 +30,7 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor | @@ -30,7 +30,7 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor | ||
| 30 | private static final String QUARTZ_JOB_STORE_DRIVER_KEY = "spring.quartz.properties.org.quartz.jobStore.driverDelegateClass"; | 30 | private static final String QUARTZ_JOB_STORE_DRIVER_KEY = "spring.quartz.properties.org.quartz.jobStore.driverDelegateClass"; |
| 31 | 31 | ||
| 32 | private static final Set<DbType> INPUT_ID_TYPES = SetUtils.asSet(DbType.ORACLE, DbType.ORACLE_12C, | 32 | private static final Set<DbType> INPUT_ID_TYPES = SetUtils.asSet(DbType.ORACLE, DbType.ORACLE_12C, |
| 33 | - DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.DB2, DbType.H2); | 33 | + DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.DB2, DbType.H2, DbType.OSCAR); |
| 34 | 34 | ||
| 35 | @Override | 35 | @Override |
| 36 | public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { | 36 | public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { |
| @@ -49,7 +49,7 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor | @@ -49,7 +49,7 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor | ||
| 49 | if (idType != IdType.NONE) { | 49 | if (idType != IdType.NONE) { |
| 50 | return; | 50 | return; |
| 51 | } | 51 | } |
| 52 | - // 情况一,用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库 | 52 | + // 情况一,用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2、神通数据库 |
| 53 | if (INPUT_ID_TYPES.contains(dbType)) { | 53 | if (INPUT_ID_TYPES.contains(dbType)) { |
| 54 | setIdType(environment, IdType.INPUT); | 54 | setIdType(environment, IdType.INPUT); |
| 55 | return; | 55 | return; |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java
| @@ -87,6 +87,7 @@ public class YudaoMybatisAutoConfiguration { | @@ -87,6 +87,7 @@ public class YudaoMybatisAutoConfiguration { | ||
| 87 | if (dbType != null) { | 87 | if (dbType != null) { |
| 88 | switch (dbType) { | 88 | switch (dbType) { |
| 89 | case POSTGRE_SQL: | 89 | case POSTGRE_SQL: |
| 90 | + case OSCAR: // 神通:与 PostgreSQL 相同,使用 nextval('序列名') 获取序列值 | ||
| 90 | return new PostgreKeyGenerator(); | 91 | return new PostgreKeyGenerator(); |
| 91 | case ORACLE: | 92 | case ORACLE: |
| 92 | case ORACLE_12C: | 93 | case ORACLE_12C: |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/enums/DbTypeEnum.java
| @@ -77,7 +77,14 @@ public enum DbTypeEnum { | @@ -77,7 +77,14 @@ public enum DbTypeEnum { | ||
| 77 | * org.opengauss 的 openGauss JDBC 驱动(jdbc:opengauss:)使用的 ProductName 为 openGauss,连接 MogDB 时也是如此; | 77 | * org.opengauss 的 openGauss JDBC 驱动(jdbc:opengauss:)使用的 ProductName 为 openGauss,连接 MogDB 时也是如此; |
| 78 | * 需要使用 PG 兼容模式(DBCOMPATIBILITY = 'PG')创建的数据库 | 78 | * 需要使用 PG 兼容模式(DBCOMPATIBILITY = 'PG')创建的数据库 |
| 79 | */ | 79 | */ |
| 80 | - OPENGAUSS(DbType.OPENGAUSS, "openGauss", "POSITION(',' || CAST(#{value} AS VARCHAR) || ',' IN ',' || #{column} || ',') > 0") | 80 | + OPENGAUSS(DbType.OPENGAUSS, "openGauss", "POSITION(',' || CAST(#{value} AS VARCHAR) || ',' IN ',' || #{column} || ',') > 0"), |
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * 神通 | ||
| 84 | + * | ||
| 85 | + * 没有 FIND_IN_SET 函数;CAST(... AS VARCHAR) 不指定长度时为 VARCHAR(1),所以不使用 CAST | ||
| 86 | + */ | ||
| 87 | + OSCAR(DbType.OSCAR, "OSCAR", "POSITION(',' || #{value} || ',' IN ',' || #{column} || ',') > 0") | ||
| 81 | 88 | ||
| 82 | ; | 89 | ; |
| 83 | 90 |
yudao-framework/yudao-spring-boot-starter-mybatis/src/test/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessorTest.java
| @@ -80,10 +80,24 @@ public class IdTypeEnvironmentPostProcessorTest { | @@ -80,10 +80,24 @@ public class IdTypeEnvironmentPostProcessorTest { | ||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | @Test | 82 | @Test |
| 83 | + public void testPostProcessEnvironment_oscarUrl() { | ||
| 84 | + // 准备参数 | ||
| 85 | + StandardEnvironment environment = buildEnvironment("jdbc:oscar://127.0.0.1:2003/OSRDB", null); | ||
| 86 | + | ||
| 87 | + // 调用 | ||
| 88 | + processor.postProcessEnvironment(environment, null); | ||
| 89 | + | ||
| 90 | + // 断言:神通不按 PostgreSQL 处理,使用序列主键(复用 PostgreKeyGenerator),但不设置 Quartz Delegate | ||
| 91 | + assertEquals("INPUT", environment.getProperty(ID_TYPE_KEY)); | ||
| 92 | + assertNull(environment.getProperty(QUARTZ_DELEGATE_KEY)); | ||
| 93 | + assertInstanceOf(PostgreKeyGenerator.class, new YudaoMybatisAutoConfiguration().keyGenerator(environment)); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + @Test | ||
| 83 | public void testPostProcessEnvironment_notNormalizedNativeUrls() { | 97 | public void testPostProcessEnvironment_notNormalizedNativeUrls() { |
| 84 | - // 海量 Vastbase 原生驱动、神通、PolarDB(兼容 Oracle)未按 PostgreSQL 处理:保持自增主键,且不设置 Quartz Delegate | 98 | + // 海量 Vastbase 原生驱动、PolarDB(兼容 Oracle)未按 PostgreSQL 处理:保持自增主键,且不设置 Quartz Delegate |
| 85 | for (String url : Arrays.asList("jdbc:vastbase://127.0.0.1:5432/ruoyi-vue-pro", | 99 | for (String url : Arrays.asList("jdbc:vastbase://127.0.0.1:5432/ruoyi-vue-pro", |
| 86 | - "jdbc:oscar://127.0.0.1:2003/OSRDB", "jdbc:polardb://127.0.0.1:1521/ruoyi-vue-pro")) { | 100 | + "jdbc:polardb://127.0.0.1:1521/ruoyi-vue-pro")) { |
| 87 | // 准备参数 | 101 | // 准备参数 |
| 88 | StandardEnvironment environment = buildEnvironment(url, null); | 102 | StandardEnvironment environment = buildEnvironment(url, null); |
| 89 | 103 |
yudao-framework/yudao-spring-boot-starter-mybatis/src/test/java/cn/iocoder/yudao/framework/mybatis/core/enums/DbTypeEnumTest.java
| @@ -22,6 +22,8 @@ public class DbTypeEnumTest { | @@ -22,6 +22,8 @@ public class DbTypeEnumTest { | ||
| 22 | // io.mogdb 的 openGauss JDBC 驱动连接 MogDB 时,返回的 ProductName 与 PostgreSQL 相同 | 22 | // io.mogdb 的 openGauss JDBC 驱动连接 MogDB 时,返回的 ProductName 与 PostgreSQL 相同 |
| 23 | assertEquals(DbType.POSTGRE_SQL, DbTypeEnum.find("PostgreSQL")); | 23 | assertEquals(DbType.POSTGRE_SQL, DbTypeEnum.find("PostgreSQL")); |
| 24 | assertEquals(DbType.KINGBASE_ES, DbTypeEnum.find("KingbaseES")); | 24 | assertEquals(DbType.KINGBASE_ES, DbTypeEnum.find("KingbaseES")); |
| 25 | + // 神通 JDBC 驱动(jdbc:oscar:)返回的 ProductName | ||
| 26 | + assertEquals(DbType.OSCAR, DbTypeEnum.find("OSCAR")); | ||
| 25 | assertNull(DbTypeEnum.find("")); | 27 | assertNull(DbTypeEnum.find("")); |
| 26 | } | 28 | } |
| 27 | 29 | ||
| @@ -32,4 +34,11 @@ public class DbTypeEnumTest { | @@ -32,4 +34,11 @@ public class DbTypeEnumTest { | ||
| 32 | assertEquals(DbTypeEnum.getFindInSetTemplate(DbType.POSTGRE_SQL), DbTypeEnum.getFindInSetTemplate(DbType.OPENGAUSS)); | 34 | assertEquals(DbTypeEnum.getFindInSetTemplate(DbType.POSTGRE_SQL), DbTypeEnum.getFindInSetTemplate(DbType.OPENGAUSS)); |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 37 | + @Test | ||
| 38 | + public void testGetFindInSetTemplate_oscar() { | ||
| 39 | + // 神通的 CAST(... AS VARCHAR) 不指定长度时为 VARCHAR(1),所以不使用 CAST | ||
| 40 | + assertEquals("POSITION(',' || #{value} || ',' IN ',' || #{column} || ',') > 0", | ||
| 41 | + DbTypeEnum.getFindInSetTemplate(DbType.OSCAR)); | ||
| 42 | + } | ||
| 43 | + | ||
| 35 | } | 44 | } |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java
| @@ -5,13 +5,16 @@ import cn.hutool.core.lang.Assert; | @@ -5,13 +5,16 @@ import cn.hutool.core.lang.Assert; | ||
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; | 6 | import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; |
| 7 | import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; | 7 | import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; |
| 8 | +import com.baomidou.mybatisplus.annotation.DbType; | ||
| 8 | import com.baomidou.mybatisplus.generator.config.DataSourceConfig; | 9 | import com.baomidou.mybatisplus.generator.config.DataSourceConfig; |
| 9 | import com.baomidou.mybatisplus.generator.config.GlobalConfig; | 10 | import com.baomidou.mybatisplus.generator.config.GlobalConfig; |
| 10 | import com.baomidou.mybatisplus.generator.config.StrategyConfig; | 11 | import com.baomidou.mybatisplus.generator.config.StrategyConfig; |
| 11 | import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; | 12 | import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; |
| 12 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; | 13 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; |
| 13 | import com.baomidou.mybatisplus.generator.config.rules.DateType; | 14 | import com.baomidou.mybatisplus.generator.config.rules.DateType; |
| 15 | +import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; | ||
| 14 | import com.baomidou.mybatisplus.generator.query.SQLQuery; | 16 | import com.baomidou.mybatisplus.generator.query.SQLQuery; |
| 17 | +import com.baomidou.mybatisplus.generator.type.ITypeConvertHandler; | ||
| 15 | import jakarta.annotation.Resource; | 18 | import jakarta.annotation.Resource; |
| 16 | import org.springframework.stereotype.Service; | 19 | import org.springframework.stereotype.Service; |
| 17 | 20 | ||
| @@ -27,6 +30,12 @@ import java.util.stream.Collectors; | @@ -27,6 +30,12 @@ import java.util.stream.Collectors; | ||
| 27 | @Service | 30 | @Service |
| 28 | public class DatabaseTableServiceImpl implements DatabaseTableService { | 31 | public class DatabaseTableServiceImpl implements DatabaseTableService { |
| 29 | 32 | ||
| 33 | + /** | ||
| 34 | + * 神通的字段类型转换:TEXT 类型的 JDBC 类型为 OTHER,按 String 处理;其它类型,使用 MyBatis Plus Generator 默认的转换 | ||
| 35 | + */ | ||
| 36 | + static final ITypeConvertHandler OSCAR_TYPE_CONVERT_HANDLER = (globalConfig, typeRegistry, metaInfo) -> | ||
| 37 | + StrUtil.equalsIgnoreCase(metaInfo.getTypeName(), "TEXT") ? DbColumnType.STRING : typeRegistry.getColumnType(metaInfo); | ||
| 38 | + | ||
| 30 | @Resource | 39 | @Resource |
| 31 | private DataSourceConfigService dataSourceConfigService; | 40 | private DataSourceConfigService dataSourceConfigService; |
| 32 | 41 | ||
| @@ -54,6 +63,9 @@ public class DatabaseTableServiceImpl implements DatabaseTableService { | @@ -54,6 +63,9 @@ public class DatabaseTableServiceImpl implements DatabaseTableService { | ||
| 54 | if (JdbcUtils.isSQLServer(config.getUrl())) { // 特殊:SQLServer jdbc 非标准,参见 https://github.com/baomidou/mybatis-plus/issues/5419 | 63 | if (JdbcUtils.isSQLServer(config.getUrl())) { // 特殊:SQLServer jdbc 非标准,参见 https://github.com/baomidou/mybatis-plus/issues/5419 |
| 55 | dataSourceConfigBuilder.databaseQueryClass(SQLQuery.class); | 64 | dataSourceConfigBuilder.databaseQueryClass(SQLQuery.class); |
| 56 | } | 65 | } |
| 66 | + if (JdbcUtils.getDbType(config.getUrl()) == DbType.OSCAR) { | ||
| 67 | + dataSourceConfigBuilder.typeConvertHandler(OSCAR_TYPE_CONVERT_HANDLER); | ||
| 68 | + } | ||
| 57 | StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder().enableSkipView(); // 忽略视图,业务上一般用不到 | 69 | StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder().enableSkipView(); // 忽略视图,业务上一般用不到 |
| 58 | if (StrUtil.isNotEmpty(name)) { | 70 | if (StrUtil.isNotEmpty(name)) { |
| 59 | strategyConfig.addInclude(name); | 71 | strategyConfig.addInclude(name); |
yudao-module-infra/src/main/resources/codegen/sql/sql.vm
| @@ -50,8 +50,8 @@ VALUES ( | @@ -50,8 +50,8 @@ VALUES ( | ||
| 50 | ); | 50 | ); |
| 51 | #end | 51 | #end |
| 52 | ## | 52 | ## |
| 53 | -## ======================= Oracle / 达梦 DM ======================= | ||
| 54 | -#elseif ($dbType.name() == 'ORACLE' || $dbType.name() == 'DM') | 53 | +## ======================= Oracle / 达梦 DM / 神通 OSCAR ======================= |
| 54 | +#elseif ($dbType.name() == 'ORACLE' || $dbType.name() == 'DM' || $dbType.name() == 'OSCAR') | ||
| 55 | -- 菜单 SQL | 55 | -- 菜单 SQL |
| 56 | INSERT INTO system_menu( | 56 | INSERT INTO system_menu( |
| 57 | name, permission, type, sort, parent_id, | 57 | name, permission, type, sort, parent_id, |
| @@ -63,7 +63,10 @@ VALUES ( | @@ -63,7 +63,10 @@ VALUES ( | ||
| 63 | ); | 63 | ); |
| 64 | 64 | ||
| 65 | -- 按钮父菜单ID | 65 | -- 按钮父菜单ID |
| 66 | --- 说明:Oracle/达梦 使用序列获取上一个插入的 ID | 66 | +-- 说明:Oracle/达梦/神通 使用序列获取上一个插入的 ID |
| 67 | +#if ($dbType.name() == 'OSCAR') | ||
| 68 | +-- 注意:神通需要 system_menu 的 id 默认使用 system_menu_seq 序列,参见 sql/tools/README.md 的神通部分 | ||
| 69 | +#end | ||
| 67 | DECLARE | 70 | DECLARE |
| 68 | v_parent_id NUMBER; | 71 | v_parent_id NUMBER; |
| 69 | BEGIN | 72 | BEGIN |
yudao-module-infra/src/test/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImplTest.java
| @@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.infra.service.db; | @@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.infra.service.db; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 4 | import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; | 4 | import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; |
| 5 | +import com.baomidou.mybatisplus.generator.config.GlobalConfig; | ||
| 5 | import com.baomidou.mybatisplus.generator.config.po.TableField; | 6 | import com.baomidou.mybatisplus.generator.config.po.TableField; |
| 6 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; | 7 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; |
| 7 | import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; | 8 | import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; |
| 9 | +import com.baomidou.mybatisplus.generator.type.TypeRegistry; | ||
| 8 | import jakarta.annotation.Resource; | 10 | import jakarta.annotation.Resource; |
| 9 | import org.apache.ibatis.type.JdbcType; | 11 | import org.apache.ibatis.type.JdbcType; |
| 10 | import org.junit.jupiter.api.Test; | 12 | import org.junit.jupiter.api.Test; |
| @@ -61,6 +63,26 @@ public class DatabaseTableServiceImplTest extends BaseDbUnitTest { | @@ -61,6 +63,26 @@ public class DatabaseTableServiceImplTest extends BaseDbUnitTest { | ||
| 61 | assertTableInfo(tableInfo); | 63 | assertTableInfo(tableInfo); |
| 62 | } | 64 | } |
| 63 | 65 | ||
| 66 | + @Test | ||
| 67 | + public void testOscarTypeConvertHandler() { | ||
| 68 | + TypeRegistry typeRegistry = new TypeRegistry(new GlobalConfig.Builder().build()); | ||
| 69 | + // 神通的 TEXT 类型,JDBC 类型为 OTHER,按 String 处理 | ||
| 70 | + assertEquals(DbColumnType.STRING, DatabaseTableServiceImpl.OSCAR_TYPE_CONVERT_HANDLER | ||
| 71 | + .convert(null, typeRegistry, buildMetaInfo(JdbcType.OTHER, "TEXT"))); | ||
| 72 | + // 其它 OTHER 类型,保持 MyBatis Plus Generator 默认的转换 | ||
| 73 | + assertEquals(DbColumnType.OBJECT, DatabaseTableServiceImpl.OSCAR_TYPE_CONVERT_HANDLER | ||
| 74 | + .convert(null, typeRegistry, buildMetaInfo(JdbcType.OTHER, "JSON"))); | ||
| 75 | + assertEquals(DbColumnType.LONG, DatabaseTableServiceImpl.OSCAR_TYPE_CONVERT_HANDLER | ||
| 76 | + .convert(null, typeRegistry, buildMetaInfo(JdbcType.BIGINT, "BIGINT"))); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + private static TableField.MetaInfo buildMetaInfo(JdbcType jdbcType, String typeName) { | ||
| 80 | + TableField.MetaInfo metaInfo = new TableField.MetaInfo(null, null); | ||
| 81 | + metaInfo.setJdbcType(jdbcType); | ||
| 82 | + metaInfo.setTypeName(typeName); | ||
| 83 | + return metaInfo; | ||
| 84 | + } | ||
| 85 | + | ||
| 64 | private void assertTableInfo(TableInfo tableInfo) { | 86 | private void assertTableInfo(TableInfo tableInfo) { |
| 65 | assertEquals("infra_config", tableInfo.getName()); | 87 | assertEquals("infra_config", tableInfo.getName()); |
| 66 | assertEquals("参数配置表", tableInfo.getComment()); | 88 | assertEquals("参数配置表", tableInfo.getComment()); |