前面已經總結了Spring JDBC 中使用JdbcTemplate的增刪改操做,這篇博文繼續總結JdbcTemplate的查詢
java
與Hibernate相比,Spring JDBC的查詢操做略顯繁雜,但在許多須要快速查尋結果給出響應的網站如電商網站,使用Spring JDBC本身寫出高效的SQL查詢比Hibernate自動生成的SQL效率更佳,Spring JDBC提供的查詢方法主要分爲單值的查詢和多值得查詢,下面分別總結。spring
Spring JDBC提供了org.springframework.jdbc.core.RowCallbackHandler回調接口以及和RowCallbackHandler功能相似的RowMapper<T>接口,因爲這兩個接口都比較簡單,就直接用例子來說解
sql
例:經過User的id獲取User對象
app
...... String sql = "SELECT u.name, u.age, u.phone, u.address FROM users.user u WHERE u.id=?"; //注意必須聲明爲final類型才能在後面的匿名內部類中使用 final User user = new User(); jdbcTemplate.query(sql, new Object[] {id}, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { user.setId(id); user.setName(rs.getString("name")); user.setAge(rs.getInt("age")); user.setPhone(rs.getString("phone")); user.setAddress(rs.getString("address")); } }); ......
經過例子能夠發現,和JDBC API的操做至關相似,只是省去建立鏈接,獲取Statement,執行SQL最後關閉鏈接的過程。若查詢出的結果集可能超過1條記錄,只須要在query方法外聲明一個final的對象List,在內部方法內部先new一個對象,再設值,最後加入List便可,processRow()方法會自動完成ResultSet的遍歷網站
例:經過User的name查詢User對象集合
ui
...... String sql = "SELECT u.name, u.age, u.phone, u.address FROM users.user u WHERE u.name=?"; List<User> users = jabcTemplate.query(sql, new Object[] {name}, new RowMapper<User>() { public User mapRow(ResultSet rs, int index) throws SQLException { User user = new User(); user.setId(rs.getString("id")); user.setName(name); user.setAge(rs.getInt("age")); user.setPhone(rs.getString("phone")); user.setAddress(rs.getString("address")); return user; } }) ......
RowMapper<T>使用了泛型,是內部方法能夠直接返回咱們指定的類型,而且由Spring幫我自動生成對應的集合,感受上使用RowMapper<T>更加方便簡單,可是RowMapper<T>在數據量很大時及其的消耗內存,好比說如今User表中有100萬條數據,我想要給全部的用戶發一封郵件,若是使用RowMapper<T>查詢全部用戶,Spring將把全部的用戶初始化一個對象並放在List中,這個List將會很是的大,甚至直接形成OutOfMemoryException,及時沒有你還須要遍歷這個List,而後每遍歷一次發一封郵件,遍歷這麼大的List想一想都以爲恐怖。而若是使用RowCallbackHandler,你能夠直接在內部方法中發郵件,咱們知道經過JDBC查詢返回的結果集並不會一次將全部匹配數據返回,而是返回一部分,具體是多少由JDBC啓動決定,當調用ResultSet#next()超過數據範圍是纔會去取下一批,這樣能夠有效的避免JVM內存開銷過大,取了下一批後,上一批會有JAVA的GC回收。spa
按照返回值得類型不用分爲了避免同的方法:
code
int queryForInt(String sql)
對象
int queryForInt(String sql, Object... args)接口
int queryForInt(String sql, Object[] args, int[] argTypes)
long queryForLong(String sql)
......
<T> T queryForObject(String sql, Class<T> requiredType)
......
單值查詢在結果集爲空或結果集超過1條數據事都會拋出異常