提取准备语句逻辑的最干净的解决方案

时间:2015-09-04 09:12:23

标签: java database prepared-statement encapsulation

我想将批处理和连接逻辑封装到一个自己的类中,如下面的代码所示,以强制正确关闭连接并使应用程序逻辑更容易。

public class SQLHelper {
    public static void insertBatched(List<String> insertStatements) {
        // do connection and batching logic here
    }
}
public class Application {
    public static void doWork() {
        // create insert statements here
        SQLHelper.insertBatched(statements);
    }
}

问题是将插入语句构建为字符串是不好的做法,应该使用预处理语句替换。当使用预处理语句时,我需要设置参数以及在同一对象上进行批处理,因此在两个类之间共享它。到目前为止我想到的解决方案:

  1. 从SQLHelper获取连接并使用它来准备语句。此解决方案的问题在于,在类之间传递连接容易出错,因为无法确保正确的资源释放
  2. 将字符串传递给SQLHelper并获取预准备语句。问题是应用程序必须在这种情况下批量插入语句并再次连接关闭
  3. 这两种解决方案都有缺点,所以我想问什么是最干净的设计解决方案才能获得最大的封装,同时仍然保证适当的资源重新发布。

1 个答案:

答案 0 :(得分:0)

如果你想手动管理SQL连接,我想你可以使用类似这样的东西

interface SqlWorker {
    public void run(Connection c);
}


class SQLHelper {
    public void execute(SqlWorker worker) throws SQLException {
        Connection c = //Get the connection
        try {
            worker.run(c);
        } finally {
            c.close();
        }
    }
}

public static void main(String[] args) throws SQLException {
    new SQLHelper().execute((c) -> {
        //do any connection sql stuff here. DB helper will clean up.
    });
}

使用此模式,您无需通过连接。
但它很容易做一些愚蠢的事情并使其崩溃。另外,如果您创建预准备语句或打开ResultSet,则需要明确关闭它们。

有问题地管理您的连接很麻烦,您可能需要考虑使用类似spring / JPA的框架,以便管理连接/事务。