java数据访问:这是java数据访问代码的好风格,还是最后尝试太多了?

时间:2009-12-21 08:35:30

标签: java data-access-layer

这是java数据访问代码的好风格,还是最终尝试过多?

public List<Item> getItems() throws ItemException {
    ArrayList<Item> items = new ArrayList<Item>();
    try {
        Connection con = ds.getConnection();
        try {
            PreparedStatement pStmt = con.prepareStatement("SELECT ....");
            try {
                ResultSet rs = pStmt.executeQuery();
                try {
                    while (rs.next()) {
                        Item item = new Item();
                        item.setItemNo(rs.getString("item_id"));
                        // ...
                        items.add(item);
                    }
                } finally {
                    rs.close();
                }
            } finally {
                pStmt.close();
            }
        } finally {
            con.close();
        }
    } catch (SQLException e) {
        throw new ItemException(e);
    }
    return items;
}

3 个答案:

答案 0 :(得分:3)

根据API文档,使用Connection隐式关闭StatementsResultSets,所以是 - 其中2个try / finally-blocks是不必要的(而且非常难看)。当您为大量查询保留单个Connection时,显式关闭语句可能很有用,以减少内存使用。

答案 1 :(得分:3)

将它与我的代码进行比较:

Connection con = null;
PreparedStatement pStmt = null;
ResultSet rs = null;
try
{
    con = ds.getConnection();
    pStmt = con.prepareStatement("SELECT ....");
    rs = pStmt.executeQuery();
    while (rs.next()) {
        Item item = new Item();

        item.setItemNo(rs.getString("item_id"));
        ...

        items.add(item);
    }
}
finally {
    rs = DBUtil.close (rs);
    pStmt = DBUtil.close (rs);
    con = DBUtil.close (rs);
}

以下是close()的样子:

public static ResultSet close (ResultSet rs) {
    try {
        if (rs != null)
            rs.close ();
    } catch (SQLException e) {
        e.printStackTrace (); 
        // Or use your favorite logging framework.
        // DO NOT THROW THIS EXCEPTION OR IT WILL
        // HIDE EXCEPTIONS IN THE CALLING METHOD!!
    }
    return null; // Make sure no one uses this anymore
}

[编辑]您需要为其他类型复制此代码。

我还把所有这些都移到了一个名为DBOp的辅助类中,所以我只需要覆盖processRow(ResultSet row)来进行实际处理,我可以省略所有样板代码。在Java 5中,DBOp的构造函数读取:

public DBOp (Logger log, DataSource ds, String sql, Object... param)

我正在传递记录器,因此我可以显示哪个实例实际上是在轮询数据。

答案 2 :(得分:2)

...并且您不应该使用getItems()方法关闭连接。看起来,您将Connection对象存储在该ds对象中。所以你应该把它留给ds来关闭它。否则,ds会返回与getConnection()方法已经关闭的连接的风险,我认为这是一种不必要的意外行为;)