在另一个类的try catch块中调用方法 [英] Invoke method in another class's try catch block

查看:453
本文介绍了在另一个类的try catch块中调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些遵循这种模式的方法

I have some methods that follow this pattern

try(Connection connection = MySqlConnection.getConnection()){
        PreparedStatement statement = connection.prepareStatement(
                "Insert into db values (NULL ,?,?,?,?,?, NULL , ?)",
                Statement.RETURN_GENERATED_KEYS);
        ...
        statement.executeUpdate();
        ...
    }
    catch(SQLException e) {
        throw new RuntimeException(e);
    }

我被告知提取与类MySqlConnection的连接的try-catch并创建一个一种执行所有逻辑并封装创建连接的新方法。因此,我不太了解这种方法,也不知道如何在不编写一些难看的模板或策略的情况下解决该问题。保持原样还是会更容易实现?

I was told to extract try-catch with connection to class MySqlConnection and create a new method that would execute all logic and encapsulate creating connection. So, I don't quite get this approach and have no idea, how to resolve it without writing some ugly templates or strategies. Would it be better to just leave it as it is, or can it be implemented in an easy way?

推荐答案

创建一个 ConnectionHelper ,它将处理异常。这有点棘手,您必须定义自己的功能接口,因为标准的使用者无法使用已检查的SQLException:

Create a ConnectionHelper that will deal with exceptions. This is a little bit tricky, you have to define your own functional interface because standard Consumer does not work with checked SQLExceptions:

public class ConnectionHelper {

    @FunctionalInterface
    public interface ConnectionConsumer {
        void accept(Connection connection) throws SQLException;
    }

    public static void doWithConnection(ConnectionConsumer connectionConsumer) {
        try (Connection connection = MySqlConnection.getConnection()) {
            connectionConsumer.accept(connection);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

然后像这样使用它:

public void doSomeUpdate() {
    ConnectionHelper.doWithConnection(connection -> {
        PreparedStatement statement = connection.prepareStatement(
                "Insert into db values (NULL ,?,?,?,?,?, NULL , ?)",
                Statement.RETURN_GENERATED_KEYS);
        statement.executeUpdate();
    });
}

这很好,只要您不必从自己的设备上返回任何东西数据库,这种情况很少发生。因此,我们需要使用另一个功能接口 ConnectionFunction 扩展帮助程序,以在需要返回对象时使用:

This works well as long as you don't have to return anything from your database, which is rarely the case. So we need to extend the helper with another functional interface, ConnectionFunction, to be used when an object needs to be returned:

public class ConnectionHelper {

    @FunctionalInterface
    public interface ConnectionConsumer {
        void accept(Connection connection) throws SQLException;
    }

    public static void doWithConnection(ConnectionConsumer connectionConsumer) {
    ...
    }

    @FunctionalInterface
    public interface ConnectionFunction<T> {
        T apply(Connection connection) throws SQLException;
    }

    public static <T> T doWithConnection(ConnectionFunction<T> connectionFunction) {
        try (Connection connection = MySqlConnection.getConnection()) {
            return connectionFunction.apply(connection);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

然后像这样使用它:

public boolean doSomeQuery() {
    return ConnectionHelper.doWithConnection(connection -> {
        PreparedStatement statement = connection.prepareStatement("SELECT * FROM table");
        return statement.execute();
    });
}

更新
2种解决方案与 SQLIntegrityConstraintViolationException

自己的运行时异常

public static class MySQLIntegrityConstraintViolationException extends RuntimeException {
    public MySQLIntegrityConstraintViolationException(Throwable cause) {
        super(cause);
    }
}

public static void doWithConnection(ConnectionConsumer connectionConsumer)       {
    try (Connection connection = MySqlConnection.getConnection()) {
        connectionConsumer.accept(connection);
    } catch (SQLIntegrityConstraintViolationException e) {
        throw new MySQLIntegrityConstraintViolationException(e);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

insertWithConnection
doWithConnection()的专用版本。再次,仅在适用的情况下使用它。

insertWithConnection: A specialized version of doWithConnection(). Again, use it only where/when applicable.

public static void insertWithConnection(ConnectionConsumer connectionConsumer) throws SQLIntegrityConstraintViolationException {
    try (Connection connection = MySqlConnection.getConnection()) {
        connectionConsumer.accept(connection);
    } catch (SQLIntegrityConstraintViolationException e) {
        throw e;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

这篇关于在另一个类的try catch块中调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆