Java 从数据库代码中删除样板文件

Java 从数据库代码中删除样板文件,java,jdbc,Java,Jdbc,似乎每次我想要执行db查询时,我都必须编写以下内容: Connection conn = null; Statement stmt = null; ResultSet rset = null; try { conn = dataSource.getConnection(); stmt = conn.prepareStatement(sql); // ...set stmt params rset = stmt.executeQuery(); while(

似乎每次我想要执行db查询时,我都必须编写以下内容:

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) { }
}
这真的是最好的方法吗?有没有办法至少减少一些混乱


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

是的,使用spingjdbc模板类()


或者,如果您不使用Spring,请复制他们在您自己的代码中使用的模板模式。

如果您已经有一个数据源,则可以用于:

  • 大大减少了样板代码
  • 具有处理具有特定运行时异常的常见数据库问题的良好能力
  • (稍后将进一步使用Spring)使用声明性事务管理
如果目前看起来太重,您可以为“样板部分”实现一些实用程序类和方法。在这种情况下,研究JdbcTemplate的源代码应该会有所帮助

制作助手方法

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

我会使用或减少混乱…

是一个非常有用的框架,我曾将其用于Spring和Hibernate过于繁杂的小型项目。它还可以进行一些对象映射。

顺便说一句,在关闭之前,您应该检查每个对象是否为null。@Robert-这不是很好,我同意应该添加null检查,但是NullPointerException将被捕获到catchs块中(以及OutOfMemoryError和可能发生的所有其他rumtime异常)。如果您打算自己编写JDBC代码,那么编写一个JDBCUtils类是值得的,它为每个JDBC类都提供了safeClose方法。这些方法应该检查null和catch/log SQLException。不要只记录异常,还要让调用者知道发生了错误,否则调用者无法对问题做出反应(在某些情况下,它可能希望这样做)。SpringJDBC模板通过将异常转换为运行时异常层次结构很好地解决了这个问题。如果可能的话,我会尝试使用Spring中的Jdbc支持,如果Spring不在项目中,我至少会复制它!看起来他们基本上已经打包了我描述的“助手”方法。下次我必须记住这一点。:-)