从数据库代码中删除样板代码

7

每当我想执行数据库查询时,似乎都需要编写以下内容:

Connection conn = null;
Statement stmt = null;
ResultSet rset = null;

try {
    conn = dataSource.getConnection();
    stmt = conn.prepareStatement(sql);
    // ...set stmt params
    rset = stmt.executeQuery();
    while(rset.next()) {
        // Do something interesting
    }
} finally {
    try { if (rset != null) rset.close(); } catch(SQLException e) { }
    try { if (stmt != null) stmt.close(); } catch(SQLException e) { }
    try { if (conn != null) conn.close(); } catch(SQLException e) { }
}

这真的是做这件事最好的方式吗?是否有一种方法至少可以减少一些混乱?

编辑:正如一些评论所指出的那样,这段代码还不够“长”。


顺便提一下,在关闭之前,你应该检查每个对象是否为空。 - Robert Munteanu
@Robert - 我同意加上空值检查是好的,但是NullPointerException将会在catch块中被捕获(连同OutOfMemoryError和其他可能发生的运行时异常一起)。 - Nick Holt
如果你要自己编写JDBC代码,那么值得编写一个JDBCUtils类,其中包含每个JDBC类的safeClose方法。这些方法应该检查null并捕获/记录SQLException。 - Nick Holt
不要仅仅记录异常,而是让调用者知道错误发生了,否则调用者无法对问题作出反应(在某些情况下,它可能希望这样做)。Spring JDBC模板通过将异常转换为运行时异常层次结构来很好地解决了这个问题。 - Peter Štibraný
5个回答

11

8
如果您已经拥有数据源,您可以使用Spring JdbcTemplate来实现以下内容:
  • 大大减少样板代码
  • 具有良好的SQL异常层次结构,以处理特定运行时异常的常见数据库问题
  • (稍后进一步使用Spring) 使用声明式事务管理
如果目前看起来过于繁重,您可以实现一些实用类和方法来处理“样板部分”。在这种情况下,学习JdbcTemplate的源代码应该会有所帮助。

Spring的SQL异常层次结构非常出色。如果可能的话,我会尝试使用Spring中的JDBC支持,或者至少将其复制到项目中,如果项目中没有使用Spring的话。 - Peter Štibraný

6

DbUtils 是一个非常有用的框架,我曾经在一些小项目中使用它,因为 Spring 和 Hibernate 太过笨重。它也能够进行一些对象映射。


1
+1 很好的发现 - 我喜欢它!看起来他们基本上打包了我所描述的“助手”方法。我得记住下次用它。 :-) - Stobor

4
创建一个辅助方法?
public class DBHelper
{
    public static Object run(string sql, List params, ResultHandler rhandler)
    {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rset = null;

        try {
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement(sql);
            int i = 0;
            for(Object p in params)
            {
                stmt.setObject(++i, p);
            }
            rset = stmt.executeQuery();
            return rhandler.handle(rset);
        } finally {
                try { rset.close(); } catch(Exception e) { }
                try { stmt.close(); } catch(Exception e) { }
                try { conn.close(); } catch(Exception e) { }
        }
    }
}

public interface ResultHandler
{
    public Object handle(ResultSet)
}

public class Test
{
    public static void main(String[] args)
    {
        String s = (String)DBHelper.run("select * from mytable where col = ?",
                Arrays.asList({"foo"}), 
                new ResultHandler
                {
                    public Object handle(ResultSet r)
                    {
                        r.first();
                        return r.getString("col2");
                    }
                }();
    }
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接