【问题标题】:How can I not throw exception at interface method signature If I throw exception in method that implements that interface?如果我在实现该接口的方法中抛出异常,我怎么能不在接口方法签名处抛出异常?
【发布时间】:2021-06-08 09:26:21
【问题描述】:

我为每个实体都有 Dao 接口。我也为每个资源实现了这些接口,例如 MYSQL.MYSQL Dao 方法抛出特定的异常,所以我需要在接口层抛出它们,但是异常是特定于 MYSQL 的,那我怎么能不要把它扔在接口层?或者我需要改变设计吗? 例如,我有 UserDao 接口:

public interface UserDao {
    boolean insertUser(Connection connection, User user) throws MySQLEXContainer.MySQLDBNotUniqueException, MySQLEXContainer.MySQLDBLargeDataException, MySQLEXContainer.MySQLDBExecutionException, SQLException;
    boolean deleteUser(Connection connection,String login) throws MySQLEXContainer.MySQLDBExecutionException, SQLException;
    boolean validateUser(Connection connection,String login,String password) throws MySQLEXContainer.MySQLDBExecutionException, SQLException;
    User findUser(Connection connection,String login) throws MySQLEXContainer.MySQLDBExecutionException, SQLException;
    boolean updateUser(Connection connection,String login,String newPassword) throws MySQLEXContainer.MySQLDBExecutionException, SQLException;
    List<User> findAllUser(Connection connection) throws MySQLEXContainer.MySQLDBExecutionException, SQLException;
}

我已经实现了所有这些,但我只展示了一个

insertUser方法的MYSQLUserDao类实现

@Override
    public boolean insertUser(Connection connection, User user) throws MySQLEXContainer.MySQLDBNotUniqueException, MySQLEXContainer.MySQLDBLargeDataException, MySQLEXContainer.MySQLDBExecutionException, SQLException {
        LOGGER.debug("Insert User Is started");
        int rowNum;
        ResultSet keys = null;
        Connection con;
        PreparedStatement statement = null;
        try {
            String query = QueriesUtil.getQuery("insertUser");
            con = connection;
            statement = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
            statement.setString(1, user.getLogin());
            statement.setString(2, PasswordUtil.generateStrongPasswordHash(user.getPassword()));
            statement.setString(3, user.getUserType());
            statement.setString(4, user.getUserEmail());
            rowNum = statement.executeUpdate();
            keys = statement.getGeneratedKeys();
            if (keys.next()) {
                user.setUserId(keys.getInt(1));
            }
        } catch (SQLException e) {
            LOGGER.error(e);
            if (e.getErrorCode() == 1062) {
                throw new MySQLEXContainer.MySQLDBNotUniqueException(String.format("%s %s", user.getLogin(), user.getUserEmail()), e.getCause());
            } else if (e.getErrorCode() == 1406) {
                throw new MySQLEXContainer.MySQLDBLargeDataException("Data Is too long", e);
            }
            throw new MySQLEXContainer.MySQLDBExecutionException("Bad execution", e);
        } finally {
            ConnectionUtil.oneMethodToCloseThemAll(keys, statement, null);
            LOGGER.debug("Close all resources");
        }
        return rowNum > 0;
    }

如果我想为 Oracle 实现 dao,我需要向 OracleDb 抛出特定的异常,因此接口的方法签名会有太多的异常。我该如何解决这个问题?

【问题讨论】:

  • 不真实。所有这些 Oracler 异常都必须有一个通用的基类异常。只需声明你的方法来抛出它。

标签: java exception design-patterns dao


【解决方案1】:

我至少可以想到两种方法来实现这一点:

  • 不要在实现中重新抛出 MySQL*异常。只需记录它们。
  • 捕获它们并将它们封装为您自己的自定义异常

阅读本文以了解处理异常的一些已知最佳实践:https://dzone.com/articles/9-best-practices-to-handle-exceptions-in-java

【讨论】:

    【解决方案2】:

    我相信你的方法太老了。几乎所有的开发者都使用某种 ORM,比如 Hibernate、MyBatis 等……

    所以,在我看来,你必须使用 ORM。它节省了很多时间。例如,如果您使用的是 Maven 项目,只需将 hibernate 依赖项添加到您的 pom.xml

    您必须编写自定义异常类并使用您的自定义类。

    【讨论】:

      猜你喜欢
      • 2013-03-14
      • 1970-01-01
      • 2017-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 2021-02-22
      相关资源
      最近更新 更多