spring學習筆記(九)

前言

        前面已經總結了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

RowCallbackHandler

        例:經過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的遍歷網站

RowMapper<T>

        例:經過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條數據事都會拋出異常

相關文章
相關標籤/搜索