Доступ к данным Java: это хороший стиль кода доступа к данным Java, или это слишком много попробовать в конце концов? - PullRequest
2 голосов
/ 21 декабря 2009

Это хороший стиль кода доступа к данным 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 ]

3 голосов
/ 21 декабря 2009

Сравните это с моим кодом:

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)

Я передаю логгер, чтобы я мог показать, какой экземпляр фактически опрашивает данные.

3 голосов
/ 21 декабря 2009

Согласно API API, Statements и ResultSets неявно закрыты с помощью Connection, поэтому да - 2 из этих блоков try / finally не нужны (и очень уродливы). Явное закрытие операторов может быть полезно, когда вы сохраняете одно соединение для большого количества запросов, чтобы уменьшить использование памяти.

2 голосов
/ 21 декабря 2009

... и вы не должны закрывать соединение в этом getItems() методе. Похоже, вы сохранили свой объект Connection в этом ds объекте. Поэтому вы должны оставить его на ds, чтобы закрыть его. В противном случае есть риск, что ds вернет уже закрытое соединение с методом getConnection (), и я предполагаю, что это нежелательное и неожиданное поведение;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...