您将如何优化(无代码重复)具有此类许多功能的Java代码

the*_*drs 3 java optimization coding-style code-cleanup

我继承的代码有许多这种形式的事务代码方法:

public void addCourseToCourses(String values)
{
    try
    {
        conn.setAutoCommit(false);
    }
    catch (SQLException e)
    {
        Logger.getLogger(connDb.class.getName()).log(Level.SEVERE, null, e);
        return;
    }
    try
    {
        stmt.executeUpdate("insert into courses values " + values);
        conn.commit();
    }
    catch (SQLException e)
    {
        try
        {
            conn.rollback();
        }
        catch (SQLException ex)
        {
            Logger.getLogger(connDb.class.getName()).log(Level.SEVERE,null, ex);
        }
    }
    finally
    {
        try
        {
            conn.setAutoCommit(true);
        }
        catch (SQLException ex)
        {
            Logger.getLogger(connDb.class.getName()).log(Level.SEVERE,null, ex);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

不同方法之间不同的变量部分是

stmt.executeUpdate("insert into courses values " + values);
Run Code Online (Sandbox Code Playgroud)

有时它是几个插入,有时它是删除.我想念使用来自C++的宏,但我确信有一种方法可以不为每个方法重复所有这些事务代码.

救命 ?

(conn和stmt是类型java.sql.Connection和java.sql.Statement的类成员)

Dav*_*ton 6

创建一个接受接口并包装异常处理的方法.

每个接口的匿名(或不是)实现都包含SQL调用,其参数等.

例如(非常粗略):

public void addCourseToCourses(final String values) {
    handleSql(new SqlCommand() {
        @Override public void run(Statement stmt) {
            stmt.executeUpdate("insert into courses values " + values);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

handleSql是静态导入类似于:

public class SqlWrapper {
    public static void handleSql(SqlCommand cmd) {
        Connection conn = // get connection;
        try {
            conn.setAutoCommit(false);
        } catch (SQLException e) {
            LOG.log(Level.SEVERE, null, e);
            return;
        }

        try {
            cmd.run();
            conn.commit();
        } catch (SQLException e) {
            cleanRollback();
        } finally {
            cleanClose();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可以添加各种钩子,看起来合理.通用版本允许各种返回类型,这可能更合适,仅取决于您实际需要的内容.

注释提到RunnableCallable,IMO Runnable是专门为螺纹(和基本接口是不通用).Callable是一个更好的选择,但我希望可以添加足够的其他钩子来处理特定于SQL或JDBC的功能,我会使用特定于应用程序的东西.因人而异.

这种模式已在各地重新发明; 采用像Spring JDBC这样的东西可能更有意义.