Вызвать метод в блоке try catch другого класса - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть несколько методов, которые следуют этому шаблону

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);
    }

Мне сказали извлечь try-catch с подключением к классу MySqlConnection и создать новый метод, который будет выполнять всю логику и инкапсулировать создание соединения.Итак, я не совсем понимаю этот подход и понятия не имею, как его решить, не написав некрасивых шаблонов или стратегий.Было бы лучше просто оставить все как есть или это можно легко реализовать?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Создайте ConnectionHelper , который будет работать с исключениями.Это немного сложно, вы должны определить свой собственный функциональный интерфейс, потому что стандартный Consumer не работает с проверенными 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();
    });
}

Thisработает хорошо до тех пор, пока вам не нужно ничего возвращать из базы данных, что редко бывает.Поэтому нам нужно расширить помощник другим функциональным интерфейсом, ConnectionFunction, который будет использоваться, когда объект должен быть возвращен:

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:

Собственное, исключение времени выполнения : Поскольку это исключение времени выполнения, вы просто добавляете try-catch там, где это необходимо.

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().Опять же, используйте его только там, где / когда это применимо.

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);
    }
}
0 голосов
/ 05 декабря 2018

Используйте функциональный интерфейс Java, чтобы отделить обработку исключений от бизнес-логики, например:

public class ExceptionHandler() {

    public R execute(Function<T,R> function, T argument) {
        try {
           return function.apply(argument)
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }
}

Теперь вы можете перейти к классу выше любой функции, которая будет содержать вашу логику, и обработка исключения будет независимой.

Кроме того, таким образом вы можете создавать множество полезных методов и классов, которые работают как прокси-сервер или которые необходимы для каждой операции, и которые будут независимы от вашей бизнес-логики.

ДляНапример, таким же образом вы можете написать:

  1. ваше собственное управление транзакциями,
  2. ведение журнала ввода и вывода
  3. проверка пользователя и прав доступа
  4. и любой другой перехватчик
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...