Java Удалить повторные попытки, поймать, наконец, шаблон из DAO - PullRequest
4 голосов
/ 16 декабря 2010

У меня есть класс DAO со многими методами, которые имеют много повторяющихся кодов в следующих строках: -

public void method1(...) {
  Connection conn = null;
  try {
      //custom code here
  } catch (SQLException e) {
     LOG.error("Error accessing the database.", e);
     throw new DatabaseException();
  } catch (QueryNotFoundException e) {
     LOG.error("Error accessing the database.", e);
     throw new DatabaseException();
  } finally {
     if (conn != null)
        connectionPool.returnConnection(conn);
  } 

public void method2(...) {
  Connection conn = null;
  try {
      //different custom code here
  } catch (SQLException e) {
     LOG.error("Error accessing the database.", e);
     throw new DatabaseException();
  } catch (QueryNotFoundException e) {
     LOG.error("Error accessing the database.", e);
     throw new DatabaseException();
  } finally {
     if (conn != null)
        connectionPool.returnConnection(conn);
  } 

Я хотел бы реструктурировать этот класс, чтобы объединить try, catch, finallyместо, чтобы избежать повторения.Как мне это сделать?

Ответы [ 4 ]

7 голосов
/ 16 декабря 2010

Создать интерфейс для ex. Исполняемые:

 public interface Executable() {

   void exec() throws SqlException();

 }

Рефакторинг каждого из ваших методов дао:

public void method1() {
   execute(new Executable() {

     @Override
     public void exec() throws SqlException() {
          // your code here
     }
  });
  } 

Создайте следующий метод execute в вашем DAO:

private void execute(Executor ex) {
    try {
      ex.exec();
    } catch(...) {
      ...
    } finally {
       ...
    }
}
2 голосов
/ 16 декабря 2010

Я думаю, вам следует использовать Spring-JDBC JdbcTemplate

Даже если вы не используете Spring для управления своим приложением, выможет программно использовать JdbcTemplate, чтобы абстрагировать все управление соединениями и обработку ошибок.

Пример кода:

List<Actor> actors = this.jdbcTemplate.query(
        "select first_name, last_name from t_actor",
        new RowMapper<Actor>() {
            public Actor mapRow(ResultSet rs, int rowNum)
            throws SQLException {
                Actor actor = new Actor();
                actor.setFirstName(rs.getString("first_name"));
                actor.setLastName(rs.getString("last_name"));
                return actor;
            }
        });

Как видите, вы имеете дело только с реальным запросом, а не с инфраструктуройвещи вокруг него.

1 голос
/ 16 декабря 2010

Я бы использовал AOP для общей схемы регистрации здесь.Например: -

<bean id="exceptionLogger" class="my.good.ExceptionLogger" />  
    <aop:config>
            <aop:pointcut id="allDaoMethods" expression="execution(* my.dao.*(..))" />
            <aop:aspect id="daoLogger" ref="exceptionLogger">
                <aop:after-throwing pointcut-ref="allDaoMethods"
                                    method="logIt"
                                    throwing="e"/>
            </aop:aspect>  
    </aop:config>

А класс ExceptionLogger может выглядеть примерно так: -

public class ExceptionLogger {
    private static Logger logger = Logger.getLogger(ExceptionLogger.class);
    public void logIt(JoinPoint jp, Exception e) {
        StringBuilder msg = new StringBuilder();
        msg.append("<whatever makes sense>");
        logger.error(msg.toString());
    }
}
0 голосов
/ 16 декабря 2010

Это похоже на решение Владимира без анонимных классов с возможностью возврата значения из таких методов.

interface DaoOperation {
    void execute() throws SQLException;
}

class Operation1 implements DaoOperation {

    public void execute() {
        // former method1
    }
}

// in case you'd ever like to return value
interface TypedDaoOperation<T> {
    T execute() throws SQLException;
}

class Operation2 implements TypedDaoOperation<String> {
    public String execute() {
        return "something";
    }
}

class DaoOperationExecutor {
    public void execute(DaoOperation o) {
        try {
            o.execute();
        } catch (SQLException e) {
            // handle it as you want
        }
    }

    public <T>T execute(TypedDaoOperation<T> o) {
        try {
            return o.execute();
        } catch (SQLException e) {
            // handle it as you want
        }
    }
}
...