在 JDBC 上的空 ResultSet 上抛出自定义异常

Throwing custom exception on an empty ResultSet on JDBC

我在尝试使用自定义异常时遇到布尔语句问题。 当使用我的代码检查数据库中是否存在优惠券时,它 returns 存在时为真。然而,当 优惠券不存在它抛出一个 sql 异常:“对空结果集的非法操作。”而不是我定制的。

我的布尔方法:

@Override
public boolean isCouponExist(int couponID) throws SQLException {
    Connection connection = pool.getConnection();

    try {
        PreparedStatement statement = connection.prepareStatement(CHECK_EXISTS);
        statement.setInt(1, couponID);
        ResultSet rs = statement.executeQuery();

        return rs.next();

    } finally {
        pool.restoreConnection(connection);

    }

}

获得一张优惠券的方法:

@Override
public Coupon getOneCoupon(int couponID) throws SQLException {
    Connection connection = pool.getConnection();

    Coupon result = null;

    try {

        PreparedStatement statement = connection.prepareStatement(GET_ONE_COUPON);
        statement.setInt(1, couponID);
        ResultSet resultSet = statement.executeQuery();
        resultSet.next();
        result = new Coupon(resultSet.getInt(1), resultSet.getInt(2), Category.categoryFor(resultSet.getInt(3)),
                resultSet.getString(4), resultSet.getString(5), resultSet.getDate(6), resultSet.getDate(7),
                resultSet.getInt(8), resultSet.getDouble(9), resultSet.getString(10));

    } finally {
        pool.restoreConnection(connection);
    }

    return result;

}

门面用于验证的方法:

public void purchaseCoupon(Coupon coupon) throws CouponExceptions, SQLException {


        if(!coup.isCouponExist(coupon.getId())) {
            throw new CouponExceptions("ERROR: Coupon " + coupon.getId() + " does not exist.");
        } 
    
    }

运行代码:

    CustomerFacade customer = (CustomerFacade) login.login("rotemb@gmail.com", "1378", ClientType.CUSTOMER);

    Coupon p1 = coupDAO.getOneCoupon(55);
    customer.purchaseCoupon(p1);

如您所见,我给了它一个不存在的 ID 号以获取异常。

堆栈跟踪:

Exception in thread "main" java.sql.SQLException: Illegal operation on empty result set.
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.result.ResultSetImpl.checkRowPos(ResultSetImpl.java:484)
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1283)
    at mysql.connector.java@8.0.18/com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:786)
    at coupon.dbdao.CouponsDBDAO.getOneCoupon(CouponsDBDAO.java:155)
    at coupon.Program.main(Program.java:49)

在尝试提供合法的优惠券 ID 时,我没有遇到任何问题。 当尝试提供非法优惠券 ID 而不是我的自定义异常时,我得到了 SQLException: “对空结果集的非法操作。”

对此还是陌生的。

您在错误的地方查找问题它不是源自 isCouponExist 而是源自 getOneCoupon 方法。

at coupon.dbdao.CouponsDBDAO.getOneCoupon(CouponsDBDAO.java:155)

问题是您在 getOneCoupon 中的代码没有考虑到该记录可能不存在于数据库中。

通读代码后,getOneMethod 中的问题是您没有考虑

resultSet.next();可能是假的

应该是

if  (resultSet.next()) {
        result = new Coupon(resultSet.getInt(1), resultSet.getInt(2), Category.categoryFor(resultSet.getInt(3)),
                resultSet.getString(4), resultSet.getString(5), resultSet.getDate(6), resultSet.getDate(7),
                resultSet.getInt(8), resultSet.getDouble(9), resultSet.getString(10));
}

关于您关于抛出自定义异常的原始问题,您应该使用 SQLException 的 try catch 子句包装您的代码。

在这种特殊情况下,您的代码仍应考虑没有结果的可能性。