【实验二】Spring框架笔记——NamedParameterJdbcTemplate与具名参数
在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于, 一旦参数的顺序发生变化, 就必须改变参数绑定.
在 Spring JDBC 框架中, 绑定 SQL 参数的另一种选择是使用具名参数(named parameter).
那么什么是具名参数?
具名参数: SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代
具名参数只在 NamedParameterJdbcTemplate 中得到支持。
在 SQL 语句中使用具名参数时, 可以在一个 Map 中提供参数值, 参数名为键
也可以使用 SqlParameterSource 参数
批量更新时可以提供 Map 或 SqlParameterSource 的数组
现在,我们在上一篇博客文章的例子的基础上,继续编写代码:
我们在applicationContext.xml后面加入具名类对象的bean:
配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <? 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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来帮助我们解决这个问题:
不过这里有两种方法,我们先介绍最一般的一种:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * 可以为参数取名字: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的另一个重载方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* * 使用具名参数时,可以使用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); } |
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人