我使用mybatis我的LinkedHashMap sqlMapper.select(sql)方法查询达梦数据库DmdbNClob类型的数据,在结果集合中没有呢,解决方式是clobAsString=1
这个问题涉及到 MyBatis 处理达梦数据库 (DM Database) 的 DmdbNClob 类型数据时的映射问题。让我搜索一下相关的技术资料和解决方案。
搜索网页
MyBatis DmdbNClob LinkedHashMap 查询结果为空 MyBatis 达梦数据库 CLOB 类型映射问题 MyBatis selectMap DM数据库 CLOB字段丢失 达梦数据库 MyBatis CLOB NCLOB 类型处理
53 个结果
根据搜索结果,我找到了您问题的根本原因和解决方案。这是达梦数据库 JDBC 驱动的已知特性/缺陷导致的。
问题原因
当使用 MyBatis 的 select 方法返回 LinkedHashMap 时,达梦数据库的 DmdbNClob 类型不会被自动转换为 Java String,而是以 DmdbNClob 对象形式存在。这会导致:
-
在 Map 中看不到该字段(可能被过滤或显示为对象引用)
-
序列化时报错(循环引用问题)
-
无法直接作为字符串使用
这是达梦数据库 JDBC 驱动的特性,不是 MyBatis 的问题。
解决方案(推荐顺序)
方案 1:JDBC URL 添加参数(最简单,推荐)
在数据库连接 URL 后添加 clobAsString=1 或 clobAsString=true:
properties
复制
# application.properties 或 application.yml
spring.datasource.url=jdbc:dm://localhost:5236/TEST?clobAsString=1
或完整配置:
properties
复制
jdbc:dm://localhost:5236?schema=your_schema&clobAsString=true&compatibleMode=mysql
原理:强制驱动将所有 CLOB/NCLOB 类型作为 String 返回。
方案 2:SQL 层面转换(无需改配置)
在 SQL 查询中使用函数将 NCLOB 转为字符串:
sql
复制
-- 使用 TO_CHAR(注意长度限制,超过 4000 会报错)
SELECT TO_CHAR(nclob_column) as nclob_column FROM table;
-- 或使用 DBMS_LOB.SUBSTR(可指定长度,最大 32767 字符)
SELECT DBMS_LOB.SUBSTR(nclob_column, 4000) as nclob_column FROM table;
-- 或使用 CAST
SELECT CAST(nclob_column AS VARCHAR(4000)) as nclob_column FROM table;
注意:TO_CHAR 有长度限制(通常 4000 字符),超长内容会被截断或报错。
方案 3:自定义 TypeHandler(灵活但代码量大)
注册自定义的 ClobTypeHandler 处理 DmdbNClob:
java
复制
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedJdbcTypes(JdbcType.CLOB)
public class DmdbNClobTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 直接按 String 读取,驱动会自动处理
return rs.getString(columnName);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}
然后在 MyBatis 配置中注册:
java
复制
@Configuration
public class MyBatisConfig {
@Bean
public ConfigurationCustomizer typeHandlerRegistry() {
return configuration -> {
// 注册自定义 Handler
configuration.getTypeHandlerRegistry().register(
Clob.class,
JdbcType.CLOB,
DmdbNClobTypeHandler.class
);
};
}
}
或 XML 配置:
xml
复制
<typeHandlers>
<typeHandler javaType="java.lang.String" jdbcType="CLOB"
handler="com.yourpackage.DmdbNClobTypeHandler"/>
</typeHandlers>
方案 4:升级达梦驱动(根本解决)
检查并升级到达梦数据库最新版 JDBC 驱动,部分版本已修复此问题。
总结建议
表格
| 场景 | 推荐方案 |
|---|---|
| 快速解决,不修改 SQL | 方案 1:URL 添加 clobAsString=1 |
| 需要精确控制长度 | 方案 2:SQL 中使用 DBMS_LOB.SUBSTR |
| 需要兼容多种数据库 | 方案 3:自定义 TypeHandler |
| 长期维护 | 方案 4:升级驱动 + 方案 1 |
最可能解决您当前问题的是方案 1,只需修改 JDBC URL 即可,无需改动代码和 SQL
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)