noear / wood

noear::微型ORM框架(支持:java sql,xml sql,annotation sql;事务;缓存;监控;等...)
Apache License 2.0
13 stars 3 forks source link

Insert方法中受影响行数记录错误 #7

Closed balajinima closed 1 hour ago

balajinima commented 2 hours ago

问题描述

在SQLer类的insert()方法的实现中,存在一个关于受影响行数记录的问题。该方法没有正确捕获stmt.executeUpdate()返回的受影响行数,导致cmd.affectRow中的数据可能不准确。

当前行为

调用了stmt.executeUpdate()但没有捕获其返回值(受影响行数) cmd.affectRow仅在返回生成的主键且为数字类型时才被设置,使用的是生成的主键值而不是受影响行数 这导致插入操作的受影响行数报告不准确

期望行为

应该捕获stmt.executeUpdate()返回的受影响行数并存储在cmd.affectRow中 方法仍然返回生成的主键值(如果可用) 受影响行数和生成主键的处理应该是独立的 方法增加注释说明返回值是自增主键

代码位置

org.noear.wood.SQLer.java
309行的insert()方法

当前代码

public long insert() throws SQLException {
    // ... 现有代码 ...

    stmt.executeUpdate();  // 返回值未被捕获

    if (cmd.context.getDialect().supportsInsertGeneratedKey()) {
        try {
            rset = stmt.getGeneratedKeys();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    if (rset != null && rset.next()) {
        Object tmp = getObject(1);
        if (tmp instanceof Number) {
            long l = ((Number) tmp).longValue();
            cmd.affectRow = new long[]{l};  // 错误:使用生成的主键作为受影响行数
            return l;
        }
    }
    // ... 剩余代码 ...
}

建议修复

public long insert() throws SQLException {
    // ... 现有代码 ...

    int affectedRows = stmt.executeUpdate();
    cmd.affectRow = new long[]{affectedRows};  // 正确记录受影响行数

    if (cmd.context.getDialect().supportsInsertGeneratedKey()) {
        try {
            rset = stmt.getGeneratedKeys();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    if (rset != null && rset.next()) {
        Object tmp = getObject(1);
        if (tmp instanceof Number) {
            return ((Number) tmp).longValue();  // 返回生成的主键,不影响cmd.affectRow
        }
    }
    // ... 剩余代码 ...
}

影响范围 这个bug影响:

插入操作的受影响行数报告 任何依赖准确受影响行数的功能 跟踪受影响行数的日志和监控系统

noear commented 1 hour ago

赞。。。直接提交个 pr !

noear commented 1 hour ago

wood 1.3.13 已发。