You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查看Java应用中createNativeQuery实际发送的SQL语句

如何查看JPA NativeQuery实际执行的SQL语句

我们有一套基于Java构建的系统,支持自定义JavaScript宏,底层使用Java实体,但我完全没有Java相关经验。当前SQL执行异常,在PHP中我会用var_dump查看最终生成的SQL语句,想了解是否有办法查看getEntityManager().createNativeQuery(sqlStr)实际发送给数据库的内容。

相关代码如下:

function insertTempHeaderRecord(filereadid, lineArray){
    try{
        var sqlStr="INSERT INTO vl_edisalesorder (filereadid, edifilename, customerid, deladdressid, contactid, "
        "pricelistid, customerref, orderdate, delivercontact, delivertelephone, taillift, bookdelivery, deliveryins, orderid "+" VALUES (:param0, :param1, :param2, :param3, :param4, :param5, :param6, :param7, :param8, :param9, :param10, :param11, :param12, :param13) ";
        getEntityManager().createNativeQuery(sqlStr)
            .setParameter("param0", filereadid)         
            .setParameter("param1", filereadid)
            .setParameter("param2", trimTo(lineArray[3],10))  //traderid
            .setParameter("param3", trimTo(lineArray[4], 10))  //deladd
            .setParameter("param4", trimTo(lineArray[5],10))   //contactid
            .setParameter("param5", "0536")
            .setParameter("param6", trimTo(lineArray[2],25))   //custref
            .setParameter("param7", Packages.java.sql.Date(orderdate.getTime()))
            .setParameter("param8", trimTo(lineArray[8],25))  //delcontact
            .setParameter("param9", trimTo(lineArray[6],20)) //deltel  
            .setParameter("param10", importer.Boolean.valueOf(lineArray[9]))  //tlrq
            .setParameter("param11", importer.Boolean.valueOf(lineArray[10])) //delbook
            .setParameter("param12", trimTo(lineArray[7],30))    //delinstr 
            .setParameter("param13", importer.Boolean.valueOf(lineArray[10]))   //delivery book in
            .executeUpdate();
    }catch(err){
        return false;
    }
    return true;
logger.info("Petestestworkflow.xml - this worked ok");
}

先提个明显的问题:你的SQL语法有误

注意看sqlStr里的列名部分,最后一个列orderid后面缺少闭合的右括号,正确的写法应该是:

var sqlStr="INSERT INTO vl_edisalesorder (filereadid, edifilename, customerid, deladdressid, contactid, "
    "pricelistid, customerref, orderdate, delivercontact, delivertelephone, taillift, bookdelivery, deliveryins, orderid) "+" VALUES (:param0, :param1, :param2, :param3, :param4, :param5, :param6, :param7, :param8, :param9, :param10, :param11, :param12, :param13) ";

这个语法错误大概率是导致执行异常的直接原因。

查看实际执行SQL的方法

1. 手动拼接参数生成调试SQL(最简单直接)

在JS宏里,你可以把参数值手动替换到SQL模板里,然后用logger.info()打印出来,就像PHP里的var_dump:

// 在executeUpdate()之前添加这段调试代码
var debugSql = sqlStr
    .replace(":param0", filereadid)
    .replace(":param1", filereadid)
    .replace(":param2", "'" + trimTo(lineArray[3],10) + "'") // 字符串类型要加单引号
    .replace(":param3", "'" + trimTo(lineArray[4],10) + "'")
    .replace(":param4", "'" + trimTo(lineArray[5],10) + "'")
    .replace(":param5", "'0536'")
    .replace(":param6", "'" + trimTo(lineArray[2],25) + "'")
    .replace(":param7", "'" + Packages.java.sql.Date(orderdate.getTime()) + "'") // 日期转字符串加单引号
    .replace(":param8", "'" + trimTo(lineArray[8],25) + "'")
    .replace(":param9", "'" + trimTo(lineArray[6],20) + "'")
    .replace(":param10", importer.Boolean.valueOf(lineArray[9]) ? 1 : 0) // 布尔值转数据库识别的0/1
    .replace(":param11", importer.Boolean.valueOf(lineArray[10]) ? 1 : 0)
    .replace(":param12", "'" + trimTo(lineArray[7],30) + "'")
    .replace(":param13", importer.Boolean.valueOf(lineArray[10]) ? 1 : 0);

logger.info("调试用SQL:" + debugSql);

打印后你就能直接看到完整的SQL,复制到数据库客户端里执行,就能快速排查问题。

2. 开启JPA的SQL日志输出

如果系统用的是Hibernate(绝大多数JPA实现都是),可以通过修改系统日志配置,开启SQL和参数的日志:

  • 将org.hibernate.SQL的日志级别设为DEBUG,会输出执行的SQL语句
  • 将org.hibernate.type.descriptor.sql.BasicBinder设为TRACE,会输出参数绑定的具体值
    不过这个方法需要你能修改系统的日志配置文件,如果权限不允许就用不了。

3. 利用JPA Query的unwrap方法(依赖系统实现)

部分JPA实现允许将NativeQuery转换为底层的具体类,比如Hibernate的NativeQueryImpl,然后获取SQL:

// 参数设置完成后,添加这段代码
var query = getEntityManager().createNativeQuery(sqlStr)
    .setParameter("param0", filereadid)         
    // ... 所有参数设置 ...

try {
    var hibernateQuery = query.unwrap(Packages.org.hibernate.query.NativeQuery.class);
    logger.info("执行的SQL:" + hibernateQuery.getQueryString());
} catch(e) {
    logger.info("无法获取SQL,可能系统不支持该方法");
}

这个方法不一定适用于所有系统,如果报错就换第一种方法。

内容的提问来源于stack exchange,提问作者Pete North

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 01:01:10