Java从DAO中删除重复的try,catch,最后的样板

我有一个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); } 

我想重组这个课程,把尝试,捕获,最后放在一个地方,以避免重复。 我怎么做到这一点?

为ex创建一个接口。 可执行文件:

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

我认为你应该使用的是Spring-JDBC的JdbcTemplate

即使您不使用spring来管理应用程序,也可以通过编程方式使用JdbcTemplate抽象出所有连接管理和error handling。

示例代码:

 List actors = this.jdbcTemplate.query( "select first_name, last_name from t_actor", new RowMapper() { 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; } }); 

如您所见,您只处理实际查询,而不是处理它周围的基础结构。

我会在这里使用AOP作为commong记录模式。 例如:-

        

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(""); logger.error(msg.toString()); } } 

这与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 execute() throws SQLException; } class Operation2 implements TypedDaoOperation { 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 execute(TypedDaoOperation o) { try { return o.execute(); } catch (SQLException e) { // handle it as you want } } }