Spring框架JdbcTemplate類中查詢方法介紹

jopen 11年前發布 | 175K 次閱讀 Spring JEE框架 JDBCTemplate

本文使用Spring2.5.6.SEC02JDK1.4作為講解環境。</span>
 </span>

Spring框架中org.springframework.jdbc.core包提供了JDBC模板類,其中JdbcTemplatecore包的核心類,其他模板類都是基于它封裝完成的。

Spring除了提供JdbcTemplate核心類外,還提供了基于JdbcTemplate實現的NamedParameterJdbcTemplate類用于支持命名參數綁定、 SimpleJdbcTemplate類用于支持JDK5+的可變參數及自動裝箱拆箱等特性。本文主要介紹JdbcTemplate核心類。

JdbcTemplate類主要提供以下四類方法:

  1. execute方法:用于執行任何SQL語句,一般用于執行DDL語句;
  2. update方法及batchUpdate方法:update方法用于執行新增、修改、刪除等語句,batchUpdate方法用于執行批處理相關語句;
  3. query方法及queryForXXX方法:用于執行查詢相關語句;
  4. call方法:用于執行存儲過程、函數相關語句。

下面將主要介紹query方法及queryForXXX方法的返回值和相關異常。

首先我們先大概了解下query方法及queryForXXX方法的調用層次。

下圖是不需要設置sql參數的方法的調用層次:


下圖是需要設置sql參數的方法的調用層次:

其中Object[] args就是設置參數用的,而int[] argTypes則是指定參數類型,參數類型定義在java.sql.Types類中。


接下來我們來看看不需要設置sql參數的查詢方法在01列,11列和51結果集中的返回值

 

01

11

51


List query
(String sql,
RowMapper rowMapper)

大小為0List

大小為1List

大小為5List


Map queryForMap
(String sql)

org.springframework.dao.
EmptyResultDataAccessException:

 Incorrect result size: expected 1, actual 0

以列名為key,大小為1Map

org.springframework.dao.
IncorrectResultSizeDataAccessException:

 Incorrect result size: expected 1, actual 5


Object queryForObject
(String sql,
RowMapper rowMapper)

org.springframework.dao.
EmptyResultDataAccessException:

 Incorrect result size: expected 1, actual 0

Object

org.springframework.dao.
IncorrectResultSizeDataAccessException:

Incorrect result size: expected 1, actual 5


Object queryForObject
(String sql,
Class requiredType)

org.springframework.dao.
EmptyResultDataAccessException:

Incorrect result size: expected 1, actual 0

類型為requiredTypeObject

org.springframework.dao.
IncorrectResultSizeDataAccessException:

 Incorrect result size: expected 1, actual 5


long queryForLong
(String sql)

org.springframework.dao.
EmptyResultDataAccessException:

 Incorrect result size: expected 1, actual 0

long

org.springframework.dao.
IncorrectResultSizeDataAccessException:

 Incorrect result size: expected 1, actual 5


int queryForInt
(String sql)

org.springframework.dao.
EmptyResultDataAccessException:

 Incorrect result size: expected 1, actual 0

int

org.springframework.dao.
IncorrectResultSizeDataAccessException:

 Incorrect result size: expected 1, actual 5


List queryForList
(String sql,
Class elementType)

大小為0List

大小為1List

大小為5List


List queryForList
(String sql)

大小為0List

List中包含1個以列名為keyMap

List中包含5個以列名為keyMap



    其中下面這些
查詢方法支持多列結果集:

  • List query(String sql, RowMapper rowMapper)
  • Map queryForMap(String sql)
  • Object queryForObject(String sql, RowMapper rowMapper)
  • List queryForList(String sql)

其他不支持多列結果集的查詢方法則會拋出IncorrectResultSetColumnCountException異常。

設置sql參數的查詢方法的返回值和上述結果類似。

從上面的結果可以看出只有返回值類型為List的方法可以接收零到多行結果集而不拋出異常,所以在使用query方法及queryForXXX方法時需要注意處理EmptyResultDataAccessExceptionIncorrectResultSizeDataAccessException這兩個異常,這兩個異常反映出數據庫表中數據可能出現了缺失或冗余。如果返回值不符合期望值時,則需要排查業務流程或者數據了。

最后我們來看看RowMapper接口,這個接口的實現類的功能是將結果集中的每一行數據封裝成用戶定義的結構,所以在查詢方法中經常會被用到。

Spring框架為我們提供了BeanPropertyRowMapper/ParameterizedBeanPropertyRowMapperColumnMapRowMapperSingleColumnRowMapper這三大便利類。

BeanPropertyRowMapper類與ParameterizedBeanPropertyRowMapper類的功能完全相同,當POJO對象和數據庫表字段完全對應或者駝峰式與下劃線式對應時,該類會根據構造函數中傳遞的class來自動填充數據。只是ParameterizedBeanPropertyRowMapper類使用泛型需要JDK5+支持。這里需要注意雖然這兩個類提供了便利,但是由于使用反射導致性能下降,所以如果需要高性能則還是需要自己去實現RowMapper接口來包裝數據。

ColumnMapRowMapper類返回一個List對象,對象中的每一個元素都是一個以列名為keyMap對象。

SingleColumnRowMapper類也返回一個List對象,對象中的每個元素是數據庫中的某列的值。注意結果集必須是單列,不然會拋出IncorrectResultSetColumnCountException異常。

現在在Spring2.5.6.SEC02JDK1.4環境下建個項目來了解下上述三個便利類。

建立數據庫表:

create table T_SPRINGJDBC_TEST

(

  my_number  NUMBER,

  my_varchar VARCHAR2(10),

  my_date    DATE

)


插入5條測試數據:


新建一個Java項目,準備依賴Jar包,Spring配置文件appContext.xml,配置數據源。

建立POJO對象:

public class MyPojo {

    private long my_Number;

    private Date my_Date;

    private String my_Varchar;

    //本文在此處省略了setter和getter方法

    public String toString() {

        return "MyPojo :{my_Number=" + my_Number + ", my_Date=" + my_Date

                + ", my_Varchar=" + my_Varchar + "}";

    }

}


建立帶main方法的類

先來了解BeanPropertyRowMapper:

public static void main(String[] args) {

        ApplicationContext ctx = new FileSystemXmlApplicationContext(

                "classpath:appContext.xml");

        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        List result = jdbcTemplate.query("select * from t_springjdbc_test",

                new BeanPropertyRowMapper(MyPojo.class));

        System.out.println(result);

    }


輸出結果如下:

[MyPojo :{my_Number=1, my_Date=2013-10-10 01:00:00.0, my_Varchar=a}, MyPojo :{my_Number=2, my_Date=2013-10-11 02:00:00.0, my_Varchar=b}, MyPojo :{my_Number=3, my_Date=2013-10-12 03:00:00.0, my_Varchar=c}, MyPojo :{my_Number=4, my_Date=2013-10-13 04:00:00.0, my_Varchar=d}, MyPojo :{my_Number=5, my_Date=2013-10-14 05:00:00.0, my_Varchar=e}]

再來了解ColumnMapRowMapper:

public static void main(String[] args) {

        ApplicationContext ctx = new FileSystemXmlApplicationContext(

                "classpath:appContext.xml");

        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        List result = jdbcTemplate.query("select * from t_springjdbc_test",

                new ColumnMapRowMapper());

        System.out.println(result);

    }


輸出結果為:

[{MY_NUMBER=1, MY_VARCHAR=a, MY_DATE=2013-10-10 01:00:00.0}, {MY_NUMBER=2, MY_VARCHAR=b, MY_DATE=2013-10-11 02:00:00.0}, {MY_NUMBER=3, MY_VARCHAR=c, MY_DATE=2013-10-12 03:00:00.0}, {MY_NUMBER=4, MY_VARCHAR=d, MY_DATE=2013-10-13 04:00:00.0}, {MY_NUMBER=5, MY_VARCHAR=e, MY_DATE=2013-10-14 05:00:00.0}]

最后了解SingleColumnRowMapper類:

public static void main(String[] args) {

        ApplicationContext ctx = new FileSystemXmlApplicationContext(

                "classpath:appContext.xml");

        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        List result = jdbcTemplate.query(

                "select my_number from t_springjdbc_test",

                new SingleColumnRowMapper());

        System.out.println(result);

    }


輸出結果為:

[1, 2, 3, 4, 5]

現在大家初步了解JdbcTemplate類中查詢方法了吧!

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!