Spring之在SpringJDBC模板中使用具名参数

在经典的 JDBC 用法中,SQL 参数是用占位符 ? 表示,并且受到位置的限制。定位参数的问题在于, 一旦参数的顺序发生变化,就必须改变参数绑定。在 Spring JDBC 框架中,绑定 SQL 参数的另一种选择是使用具名参数(named parameter)。 

具名参数

SQL 按名称(以冒号开头)而不是按位置进行指定。

具名参数更易于维护,也提升了可读性。

具名参数由框架类在运行时用占位符取代。

具名参数只在 org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate 中得到支持,其API如下:

public int update(String sql, Map<String, ?> paramMap) throws DataAccessException

public int update(String sql, SqlParameterSource paramSource) throws DataAccessException

public int[] batchUpdate(String arg0, Map<String, ?>[] arg1)

public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs)

在 SQL 语句中使用具名参数时,可以在一个 Map 中提供参数值,参数名为键。也可以使用 SqlParameterSource 参数。批量更新时可以提供 Map 或 SqlParameterSource 的数组。

示例

1. 在MySQL中添加表结构

create table user(id int(10),username varchar(100),password varchar(100));

2. 添加模型类

package xyz.huning.spring4.jdbc;

public class User {

	private int id;
	
	private String name;
	
	private String password;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", password=" + password
				+ "]";
	}
	
}

3. 添加DB配置文件

###################################################
     ##   database configuration   ##
###################################################
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring4jdbc
jdbc.user=root
jdbc.password=root


###################################################
     ##   c3p0 configuration   ##
###################################################
c3p0.initialPoolSize=3
c3p0.minPoolSize=2
c3p0.maxPoolSize=10
c3p0.maxIdleTime=28000
c3p0.idleConnectionTestPeriod=3600

4. 添加Spring配置文件

<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
	
	<context:component-scan base-package="xyz.huning.spring4.jdbc.dao"></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="${c3p0.initialPoolSize}"></property>
		<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
		<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
		<property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
		<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"></property>
	</bean>
	
	<!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数, 其没有无参数的构造器, 所以必须为其构造器指定参数 -->
	<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource"></constructor-arg>	
	</bean>
	
</beans>

5. 添加测试类

package xyz.huning.spring4.jdbc.namedparameter;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

import xyz.huning.spring4.jdbc.User;


public class Main {

	public static void main(String[] args) throws SQLException {
		
		ApplicationContext ctx = new ClassPathXmlApplicationContext("jdbc-namedparameter.xml");

		/**
		 * 使用NamedParameterJdbcTemplate的优缺点:
		 * 优点:有多个参数时不用再去对应位置,直接对应参数名,便于维护,减少错误的概率
		 * 缺点:较为麻烦
		 */
		NamedParameterJdbcTemplate npJdbcTemplate = ctx.getBean("namedParameterJdbcTemplate", NamedParameterJdbcTemplate.class);
		String sql = "insert into user (id,username,password) values (:id,:name,:pass)";
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("id", "100");
		paramMap.put("name", "BluceLi");
		paramMap.put("pass", "585858");
		npJdbcTemplate.update(sql, paramMap);
		
		/**
		 * 批量更新
		 */
		@SuppressWarnings("unchecked")
		Map<String,Object>[] paramMaps = new HashMap[1];
		paramMaps[0] = paramMap;
		npJdbcTemplate.batchUpdate(sql, paramMaps);
		
		/**
		 * 对上面方法的改进
		 * 
		 * 通过SqlParameterSource可以传入对象,sql中名称占位符(:id,:name,:password)必须和对象的属性名相同。
		 * 
		 * 使用具名参数时,可以使用update(String sql, SqlParameterSource paramSource)方法进行更新操作
		 * 1. SQL语句中的参数名和类的属性一致
		 * 2. 使用SqlParameterSource的BeanPropertySqlParameterSource实现类作为参数
		 * 
		 */
		sql = "insert into user (id,username,password) values (:id,:name,:password)";
		User user = new User();
		user.setId(99);
		user.setName("TomQi");
		user.setPassword("181818");
		
		SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user);
		npJdbcTemplate.update(sql, paramSource);
		
		/**
		 * 批量更新
		 */
		SqlParameterSource[] paramSources = new BeanPropertySqlParameterSource[1];
		paramSources[0] = paramSource;
		npJdbcTemplate.batchUpdate(sql, paramSources);
		
		((ClassPathXmlApplicationContext)ctx).close();
		
	}
}

6. 执行结果


Spring之在SpringJDBC模板中使用具名参数


  

相关推荐