Spring框架JdbcTemplate類中查詢方法介紹
本文使用Spring2.5.6.SEC02和JDK1.4作為講解環境。</span> Spring框架中org.springframework.jdbc.core包提供了JDBC模板類,其中JdbcTemplate是core包的核心類,其他模板類都是基于它封裝完成的。
</span>
Spring除了提供JdbcTemplate核心類外,還提供了基于JdbcTemplate實現的NamedParameterJdbcTemplate類用于支持命名參數綁定、 SimpleJdbcTemplate類用于支持JDK5+的可變參數及自動裝箱拆箱等特性。本文主要介紹JdbcTemplate核心類。
JdbcTemplate類主要提供以下四類方法:
- execute方法:用于執行任何SQL語句,一般用于執行DDL語句;
- update方法及batchUpdate方法:update方法用于執行新增、修改、刪除等語句,batchUpdate方法用于執行批處理相關語句;
- query方法及queryForXXX方法:用于執行查詢相關語句;
- call方法:用于執行存儲過程、函數相關語句。
下面將主要介紹query方法及queryForXXX方法的返回值和相關異常。
首先我們先大概了解下query方法及queryForXXX方法的調用層次。
下圖是不需要設置sql參數的方法的調用層次:
下圖是需要設置sql參數的方法的調用層次:
其中Object[] args就是設置參數用的,而int[] argTypes則是指定參數類型,參數類型定義在java.sql.Types類中。
接下來我們來看看不需要設置sql參數的查詢方法在0行1列,1行1列和5行1列結果集中的返回值
0行1列 |
1行1列 |
5行1列 |
||
List query |
大小為0的List |
大小為1的List |
大小為5的List |
|
Map queryForMap |
org.springframework.dao. |
以列名為key,大小為1的Map |
org.springframework.dao. |
|
Object queryForObject |
org.springframework.dao. |
Object |
org.springframework.dao. |
|
Object queryForObject |
org.springframework.dao. |
類型為requiredType的Object |
org.springframework.dao. |
|
long queryForLong |
org.springframework.dao. |
long |
org.springframework.dao. |
|
int queryForInt |
org.springframework.dao. |
int |
org.springframework.dao. |
|
List queryForList |
大小為0的List |
大小為1的List |
大小為5的List |
|
List queryForList |
大小為0的List |
List中包含1個以列名為key的Map |
List中包含5個以列名為key的Map |
其中下面這些查詢方法支持多列結果集:
- 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方法時需要注意處理EmptyResultDataAccessException和IncorrectResultSizeDataAccessException這兩個異常,這兩個異常反映出數據庫表中數據可能出現了缺失或冗余。如果返回值不符合期望值時,則需要排查業務流程或者數據了。
最后我們來看看RowMapper接口,這個接口的實現類的功能是將結果集中的每一行數據封裝成用戶定義的結構,所以在查詢方法中經常會被用到。
Spring框架為我們提供了BeanPropertyRowMapper/ParameterizedBeanPropertyRowMapper,ColumnMapRowMapper和SingleColumnRowMapper這三大便利類。
BeanPropertyRowMapper類與ParameterizedBeanPropertyRowMapper類的功能完全相同,當POJO對象和數據庫表字段完全對應或者駝峰式與下劃線式對應時,該類會根據構造函數中傳遞的class來自動填充數據。只是ParameterizedBeanPropertyRowMapper類使用泛型需要JDK5+支持。這里需要注意雖然這兩個類提供了便利,但是由于使用反射導致性能下降,所以如果需要高性能則還是需要自己去實現RowMapper接口來包裝數據。
ColumnMapRowMapper類返回一個List對象,對象中的每一個元素都是一個以列名為key的Map對象。
SingleColumnRowMapper類也返回一個List對象,對象中的每個元素是數據庫中的某列的值。注意結果集必須是單列,不然會拋出IncorrectResultSetColumnCountException異常。
現在在Spring2.5.6.SEC02和JDK1.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類中查詢方法了吧!