spring學習筆記(八)

前言

       今天整理下Spring JDBC,相信很多的Java開發人員都有過使用JDBC API的經歷,可是每一次的操做都須要獲取連接,建立Statement,異常處理,最後釋放資源,這樣的工做乏味而枯燥的,好在Spring JDBC爲咱們提供了對JDBC API的輕量封裝,這樣咱們就能夠輕鬆的使用JDBC了.java

JdbcTemplate

        Spring JDBC提供了JdbcTmplate用於完成JDBC操做,JdbcTmplate對JDBC API進行了封裝,獲取連接,建立Statement,異常處理,最後釋放資源這些工做都交給了他幫咱們處理,咱們只須要編寫SQL,而後執行SQL獲取結果便可,同時JdbcTmplate中還提供了幾個用於設置底層JDBC API的屬性以下:spring

  • queryTimeout:用於設置JdbcTemplate所建立的Statement的最大查詢超時時間,默認爲0,即表示使用底層JDBC API的默認設置sql

  • fetchSize:設置底層的ResultSet每次衝數據庫放回的行數,默認爲0,即便用底層jdbc默認配置,這個屬性和影響性能,設置過大,將大量在用內存,設置太小,從數據庫讀取次數將增長都很影響性能數據庫

  • ignoreWarnings:是否忽略SQL警告,默認true,當爲false時,出現警告JdbcTmplate將拋出異常數組

JdbcTmplate的配置相對簡單,只須要在Spring配置中向JdbcTmplate注入DataSource既能夠獲取JdbcTmplate進行操做,因此這裏就再也不介紹配置直接開始使用。性能

JdbcTemplate增刪改操做

        增刪改操做均可以使用JdbcTemplate的 int update(String sql, Object[] params)執行,由於增刪改操做都返回影響的行數,此方法還有不少的重載方法:fetch

  • int update(String sql):爲不帶佔位符的SQL語句提供方便spa

  • int update(String sql, Object[] params, int[] argTypes):除了佔位符的入參數組外,後面的數組用於指定前面入參的類型,值爲java.sql.Types類中的常量屬性值code

  • int update(String sql, PreparedStatementSetter pss):PreparedStatementSetter 是一個回調接口,當你但願能夠本身爲PreparedStatement設置時可使用,例:對象

  • jdbcTemplate.update(sql, new PreparedStatementSetter() {
        public void setValues(PreparedStatement ps) throws SQLException {
            ps.setString(1, "test1");
            ps.setString(2, "test2");
            ps.setString(3, "test3");
        }
    });
  • int update(PreparedStatementCreator psc):PreparedStatementCreator 也是一個回調接口,當你但願本身建立PreparedStatement時可使用,例:

  • jdbcTemplate.update(new PreparedStatementCreator() {
        public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
            PreparedStatement ps = conn.preparedStatement(sql);//字符串sql必須是final的才能在內部類中使用 
            ps.setString(1, "test1");
            ps.setString(2, "test2");
            ps.setString(3, "test3");
            return ps;
        }
    });
  • int update(PreparedStatementCreator psc,PreparedStatementSetter pss):雙回調用法是上面兩種的結合

返回數據庫的表自增值

        咱們常常會將表的主鍵設置成自增的,不少時候都會遇到插入一條數據後須要獲得新插入數據的主鍵值得狀況,一般咱們會先執行insert語句後再去select出這個值,JDBC3.0中當新增記錄時,容許將數據庫自動產生的主鍵值綁定到Statement或者PrepareStatement中:

  • Statement可使用int executeUpdate(String sql, int autoGeneratedKeys)

  • PrepareStatement能夠在建立時設置使用Connection的PrepareStatement prepareStatement(String sql,  int autoGeneratedKeys)方法

autoGeneratedKeys的值都應該設置爲Statement.RETURN_GENERATED_KEYS,再執行SQL獲取到ResultSet對象後,調用ResultSet對象的getInt()方法既能夠得到自增主鍵值。

        Spring利用這一技術,提供了一個能夠返回新增記錄對應主鍵值的方法:

            int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)

        org.springframework.jdbc.support.KeyHolder是一個回調接口,Spring使用他保存返回的主鍵,該接口有以下方法:

  • Number getKey() throws InvalidDataAccessApiUsageException:當一次僅插入一條且主鍵爲數字類型時使用此方法返回主鍵

  • Map<String, Object> getKeys() throws InvalidDataAccessApiUsageException:一次僅插入一條且是複合主鍵用這個方法key爲列名,value爲值

  • List<Map<String, Object>getKeyList():當新增多條記錄是用這個方法返回

上述方法使用實例:

......
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PrepareStatementCreator() {
    public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
        PreparedStatement ps = conn.preparedStatement(sql);//字符串sql必須是final的才能在內部類中使用 
        ps.setString(1, "test1");
        ps.setString(2, "test2");
        ps.setString(3, "test3");
        return ps;
}, keyHolder);
//以後使用keyHolder對象就能夠得到自增的主鍵值了
int id = keyHolder.getKey().intValue();

批量更改數據

        通常狀況下可使用for循環執行SQL語句實現批量更改,可是這樣作是效率低下的,由於底層代碼沒更改一次都須要獲取鏈接建立Statement,執行SQL再釋放資源,而Spring提供的int[] batchUpdate(String[] sql)方法只會鏈接一次而後將SQL批量的交個數據庫,這樣會效率更高,這個方法也有一個重載方法:

        int[] batchUpdate(String sql, BatchPreparedStatementSetter pss)

例:

......
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
    public int getBatchSize() {
        //viewSpaces是PrepareStatement的傳入參數List
        return viewSpaces.size();
    }
    
    public void setValue(PreparedStatement ps, int index)
                throws SQLException {
        ViewSpace viewSpace = viewSpaces.get(index);
        ps.setString(1, viewSpace.getSapceName());
        ......
    }
});
相關文章
相關標籤/搜索