2010-12-16 58 views
4

样板我有一个包含了沿线的很多重复的代码很多方法DAO类: -的Java删除重复尝试,捕捉,最后从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); 
    } 

我想重组这一类把这个尝试,赶上,最后在一个地方,以避免重蹈覆辙。我怎么做到这一点?

回答

6

创建前的接口。可执行文件:

public interface Executable() { 

    void exec() throws SqlException(); 

} 

重构每个DAO的方法来:

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

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

创建以下方法在你的DAO执行:

private void execute(Executor ex) { 
    try { 
     ex.exec(); 
    } catch(...) { 
     ... 
    } finally { 
     ... 
    } 
} 
+0

是的,如果JdbcTemplate不是一个选项,那是我要提出的下一个模式+1) – 2010-12-16 11:06:46

1

我会在这里使用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

这对我很有意思。你能解释更多吗?我处于同样的情况 – 2010-12-16 11:02:07

+0

你想让我更多地解释什么?您可以在我提供的链接上阅读AOP。我还给出了aop配置示例和一个示例异常类。 – CoolBeans 2010-12-16 11:06:26

+0

这也是一个基于弹簧的解决方案。阅读本章:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html(它很难阅读,但它是值得的努力),也阅读'AspectJ in Action(2nd ed)':http://www.manning.com/laddad2/它提供了有或没有Spring的AOP的深度报道 – 2010-12-16 11:09:51

2

我认为你应该使用什么是Spring-JDBCJdbcTemplate

即使你不使用spring来ma nage你的应用程序,你可以编程使用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; 
      } 
     }); 

正如你所看到的,你处理实际的查询只,不与周围的基础设施的东西。

0

这与Vladimirs解决方案类似,没有匿名类,可以从这些方法返回值。

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