为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。 【DM版本】:DM8 【操作系统】:麒麟 【CPU】:飞腾 【问题描述】*:同一版本hibernate,使用oracle驱动能打印完整带参数的sql,使用达梦驱动只打印带占位符的sql,参数是分开显示的,对于多动态参数的sql,可读性差
关于这个需求,我们这边做了一次实测确认,先同步结论:达梦驱动与 Oracle 驱动在 toString() 上的行为是一致的,两边都没有重写。
toString()
用反射绕过构造器直接观察 PreparedStatement 的 toString():
PreparedStatement
达梦 : dm.jdbc.driver.DmdbPreparedStatement@6e0be858 Oracle : oracle.jdbc.driver.T4CPreparedStatement@76ccd017
两者输出的都是 Object 默认的"类名@hash"。Oracle 侧我们再查了 ojdbc6 (11.2.0.4) 与 ojdbc8,OracleStatement / T4CPreparedStatement 也都没有重写。
Object
OracleStatement
T4CPreparedStatement
"只打印带占位符的 SQL、参数分开显示",这是 Hibernate 原生日志的固定形态:
Hibernate: select ... from t where id=? TRACE BasicBinder - binding parameter [1] as [BIGINT] - [1]
这段日志由 Hibernate 自身产生,与 JDBC 驱动无关,在 Oracle 环境下形态完全相同。
通常能看到"单行完整 SQL"的,是日志代理层做了参数回填,例如 p6spy / log4jdbc / datasource-proxy / Druid StatFilter。MyBatis 的 StdOutImpl 同样是 Preparing: + Parameters: 两行,并非单行。
StdOutImpl
Preparing:
Parameters:
想请您协助确认两点,便于进一步定位:
show_sql
format_sql
PreparedStatement 的绑定值在驱动内部并不以 Java 对象形式保留,而是直接写入通信协议缓冲区,因此无法在 toString() 时回填成完整 SQL。Oracle 驱动同样不提供这项能力,原因也在于此。
p6spy(推荐,跨数据库行为一致):
# spy.properties driverlist=dm.jdbc.driver.DmDriver appender=com.p6spy.engine.spy.appender.Slf4JLogger logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat customLogMessageFormat=%(currentTime) | %(executionTime) ms | %(sqlSingleLine)
它通过代理 PreparedStatement.setXxx() 自行记录参数并回填,Oracle 与达梦的输出格式完全一致。
PreparedStatement.setXxx()
datasource-proxy:
ProxyDataSourceBuilder.create(originalDataSource) .logQueryBySlf4j(INFO) .multiline() .build();
如果按上述方式配置后两侧仍有差异,欢迎把日志片段发上来,我们再一起看。
关于这个需求,我们这边做了一次实测确认,先同步结论:达梦驱动与 Oracle 驱动在
toString()上的行为是一致的,两边都没有重写。一、实测结果
用反射绕过构造器直接观察
PreparedStatement的toString():两者输出的都是
Object默认的"类名@hash"。Oracle 侧我们再查了 ojdbc6 (11.2.0.4) 与 ojdbc8,OracleStatement/T4CPreparedStatement也都没有重写。二、日志差异的来源
"只打印带占位符的 SQL、参数分开显示",这是 Hibernate 原生日志的固定形态:
这段日志由 Hibernate 自身产生,与 JDBC 驱动无关,在 Oracle 环境下形态完全相同。
通常能看到"单行完整 SQL"的,是日志代理层做了参数回填,例如 p6spy / log4jdbc / datasource-proxy / Druid StatFilter。MyBatis 的
StdOutImpl同样是Preparing:+Parameters:两行,并非单行。想请您协助确认两点,便于进一步定位:
show_sql/format_sql配置是否完全一致?三、驱动为什么无法直接输出完整 SQL
PreparedStatement的绑定值在驱动内部并不以 Java 对象形式保留,而是直接写入通信协议缓冲区,因此无法在toString()时回填成完整 SQL。Oracle 驱动同样不提供这项能力,原因也在于此。四、推荐做法
p6spy(推荐,跨数据库行为一致):
# spy.properties driverlist=dm.jdbc.driver.DmDriver appender=com.p6spy.engine.spy.appender.Slf4JLogger logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat customLogMessageFormat=%(currentTime) | %(executionTime) ms | %(sqlSingleLine)它通过代理
PreparedStatement.setXxx()自行记录参数并回填,Oracle 与达梦的输出格式完全一致。datasource-proxy:
如果按上述方式配置后两侧仍有差异,欢迎把日志片段发上来,我们再一起看。