Java Delete retry, catch finally template from DAO

I have a DAO class with many methods that have a lot of repeating code in lines: -

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

I would like to rebuild this class to put try, catch, finally, in one place to avoid repetition. How to do it?

+4
source share
4 answers

Create an interface for ex. Executable file:

  public interface Executable() { void exec() throws SqlException(); } 

Reorganize each of your dao methods into:

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

Create the following method in the DAO:

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

I think you should use Spring -JDBC JdbcTemplate

Even if you are not using spring to manage your application, you can programmatically use JdbcTemplate to abstract all connection management and error handling.

Code example:

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

As you can see, you are dealing only with the actual request, and not with the infrastructure material around it.

+2
source

I would use AOP to share the registration template. For instance: -

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

And the ExceptionLogger class could be something like: -

 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()); } } 
+1
source

This is similar to Vladimir's decision without anonymous classes with the ability to return the value from such methods.

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

Source: https://habr.com/ru/post/1332334/


All Articles