1 回答

TA貢獻1890條經驗 獲得超9個贊
您可以傳入一個策略來告訴該方法如何將行映射到對象上的字段。
這就是 spring-jdbc 所做的,它將RowMapper定義為:
public interface RowMapper<T> {
T mapRow(ResultSet resultSet, int rowNum) throws SQLException;
}
這就是您可以更改方法的方式,包括合并 rowMapper:
public static <T> List<T> queryList(String query, Connection conn, RowMapper<T> rowMapper) throws SQLException {
LOGGER.debug("Executing query = {}", query);
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
List<> list = new ArrayList<>();
while (rs.next()) {
list.add(rowMapper.mapRow(rs, list.size() + 1));
}
return list;
} finally {
DBUtil.closeResultSet(rs);
DBUtil.closeStatement(stmt);
LOGGER.debug("Finished query = {}", query);
}
}
在這里捕獲所有異常并不好,因為如果出現問題,您希望能夠使用異常來退出當前操作。否則,您將在日志中有多個錯誤堆棧跟蹤,其中一個是發生錯誤的地方,另一個是下游,當您的代碼期望出現不是由于前一個錯誤導致的結果時,您的代碼會失敗。當第一個錯誤發生時快速失敗。
下一步將參數化您的查詢,因此您不必將參數值括在引號中或擔心 sql 注入。有關spring-jdbc 如何處理此問題的示例,請參見此答案。
我把連接的東西移出了方法;傳入連接允許您在同一個 JDBC 本地事務中執行多個 sql 語句。(連接仍然需要關閉,這只是錯誤的地方。)
同樣在這里傳遞這個句柄是違反德墨忒耳法則的:
特別是,一個對象應該避免調用另一個方法返回的成員對象的方法。對于許多使用點作為字段標識符的現代面向對象語言,該法則可以簡單地表述為“僅使用一個點”。也就是說,代碼 abMethod() 違反了 a.Method() 沒有的規律。打個比方,想讓狗走路,不是直接命令狗腿走路,而是直接讓狗走路。取而代之的是命令狗,然后狗命令自己的腿。
即使您只做只讀的事情,讓查詢共享事務也可以提高一致性并提高性能。使用 Spring 使用事務不那么痛苦,您可以使用注釋以聲明方式實現事務,以顯示您希望邊界在哪里。
這里的全局答案是:最好采用一個預先存在的工具(spring-jdbc 或類似的東西),它們已經解決了你甚至還沒有考慮過的問題,而不是零碎地重新發明它,這就是你顯然要走的路。
添加回答
舉報