Spring框架筆記(二十五)——NamedParameterJdbcTemplate與具名參數

在經典的 JDBC 用法中, SQL 參數是用佔位符 ? 表示,而且受到位置的限制. 定位參數的問題在於, 一旦參數的順序發生變化, 就必須改變參數綁定. java

在 Spring JDBC 框架中, 綁定 SQL 參數的另外一種選擇是使用具名參數(named parameter).spring

 

那麼什麼是具名參數?sql

具名參數: SQL 按名稱(以冒號開頭)而不是按位置進行指定. 具名參數更易於維護, 也提高了可讀性. 具名參數由框架類在運行時用佔位符取代數據庫

具名參數只在 NamedParameterJdbcTemplate 中獲得支持。數組


在 SQL 語句中使用具名參數時, 能夠在一個 Map 中提供參數值, 參數名爲鍵app

也可使用 SqlParameterSource 參數框架

批量更新時能夠提供 Map 或 SqlParameterSource 的數組ide


如今,咱們在上一篇博客文章的例子的基礎上,繼續編寫代碼:性能

咱們在applicationContext.xml後面加入具名類對象的bean:this

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

	<!-- 自動掃描的包 -->
	<context:component-scan base-package="com.happBKs.spring.jdbcSpring"></context:component-scan>



	<!-- 導入資源文件 -->
	<context:property-placeholder location="classpath:db.properties" />

	<!-- 配置c3p0數據源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
	</bean>
	
	<!-- 配置jdbc模板類 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 配置 NamedParameterJdbcTemplate,該對象可使用具名參數。
	但它沒有無參構造器,因此必須爲其制定構造參數,這裏指定的是出c3p0數據源
	-->
	<bean id="namedParameterJdbcTemplate"
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource"></constructor-arg>
	</bean>
	
</beans>

以後咱們再也不使用上次提到的EmployeeBean類,由於咱們已經知道了Spring JDBC並不能提供像Hibernate等ORM框架那樣的類屬性的級聯映射,因此咱們把屬性department改成了deptId。

package com.happBKs.spring.jdbcSpring;

public class EmployeeBean2 {
	Integer id;
	String lastName;
	String email;
	Integer deptId;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Integer getDeptId() {
		return deptId;
	}
	public void setDeptId(Integer deptId) {
		this.deptId = deptId;
	}
	public EmployeeBean2(Integer id, String lastName, String email,
			Integer deptId) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.deptId = deptId;
	}
	public EmployeeBean2() {
		super();
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "EmployeeBean2 [id=" + id + ", lastName=" + lastName
				+ ", email=" + email + ", deptId=" + deptId + "]";
	}


	
}

而後,咱們來使用具名參數來完成咱們以前提到的各類更新操做:

好比以前咱們插入一個記錄的寫法是:



這種寫法,賦值的參數沒有給予具體的名稱,只經過佔位符?來完成佔位,經過賦值參數的順序來對應相應的參數。如今咱們能夠藉助於org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate來幫助咱們解決這個問題:

不過這裏有兩種方法,咱們先介紹最通常的一種:

/*
	 * 能夠爲參數取名字:ln,:email,:deptid
	 * 優勢:若是有多個參數,不用去糾結於參數的位置順序,直接對應參數名,便於維護
	 * 缺點:較爲麻煩
	 */
	@Test
	public void testNamedParameterJdbcTemplate(){
		//以前不適用具名參數的用法:
		//String sql="insert employee(last_name,email,dept_id) values(?,?,?)";
		//咱們給予參數賦值必須依賴於?的順序
		
		// 使用具名參數的用法:
		String sql="insert employee(last_name,email,dept_id) values(:ln,:email,:deptid)";
		Map<String,Object> paramMap=new HashMap<String, Object>();
		paramMap.put("ln", "超級無敵銀河最強臨時工");
		paramMap.put("email", "super@qq.com");
		paramMap.put("deptid", 4);
		namedParameterJdbcTemplate.update(sql,paramMap);
	}

這裏,SQL語句中的賦值參數被用":"的形式給出,這裏就是具名參數。而後咱們能夠經過一個Map對象,Map的key是咱們的具名參數,而value則是參數的值,而後經過NamedParameterJdbcTemplate類對象的方法update來完成曾刪改操做。

運行結果:


不過,這種方法仍是有比較麻煩的地方,咱們須要在map對象中逐一指定參數。

這時候,你可能不由感慨,仍是ORM框架好,類屬屬性可以自動與數據庫表的字段映射。這裏Spring JDBC在具名參數賦值時也考慮了相似的解決方法。

下面,我來介紹具名參數的第二種方法:

咱們須要將具名參數定義爲與類的屬性名稱同樣的名字,而後,能夠建立一個相應的類的對象,並調用相應屬性的set方法賦值,以後,咱們就調用update的另外一個重載方法:

/*
	 * 使用具名參數時,可使用int org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(String sql, SqlParameterSource paramSource) throws DataAccessException
		方法進行更新操做:
		1. SQL語句中的具名參數與類的屬性名一致
		2. 使用接口SqlParameterSource的BeanPropertySqlParameterSource實現類做爲參數
		

	 */
	@Test
	public void testNamedParameterJdbcTemplate2(){
		//以前不適用具名參數的用法:
		//String sql="insert employee(last_name,email,dept_id) values(?,?,?)";
		//咱們給予參數賦值必須依賴於?的順序
		
		// 使用具名參數的用法:
		String sql="insert employee(last_name,email,dept_id) values(:lastName,:email,:deptId)";
		EmployeeBean2 e=new EmployeeBean2();
		e.setLastName("haha");
		e.setEmail("haha@qq.com");
		e.setDeptId(4);
		SqlParameterSource sqlParameterSource=new BeanPropertySqlParameterSource(e);
		namedParameterJdbcTemplate.update(sql,sqlParameterSource);
	}

運行結果:

相關文章
相關標籤/搜索