当前位置: 首页 > article >正文

NamedParameterJdbcTemplate 使用方法及介绍

NamedParameterJdbcTemplate是 Spring 框架中用于数据库操作的核心类之一,它拓展了JdbcTemplate,通过封装实现命名参数特性,相比传统占位符?,命名参数可读性和维护性更强,能有效避免参数顺序混淆问题。

一、核心支持类

1. SqlParameterSource 实现类

  • MapSqlParameterSource:简单封装java.util.Map,可通过addValue方法添加参数,也能基于现有Map构建,如new MapSqlParameterSource(paramMap) 。
  • BeanPropertySqlParameterSource:封装 JavaBean 对象,依据对象属性值为命名参数赋值,适用于参数来自对象属性的场景。
  • EmptySqlParameterSource:为空的SqlParameterSource,常用于占位,如查询语句无实际参数时使用EmptySqlParameterSource.INSTANCE。

2. RowMapper 接口实现类

  • SingleColumnRowMapper:用于处理单列数据查询结果,将查询结果映射为List<String>、Integer等单列数据类型。
  • BeanPropertyRowMapper:可将查询结果匹配到对象,如List<XxxVO>,且会自动将数据库字段的下划线命名转换为驼峰命名属性。

二、数据库操作方法

1. 插入 / 修改 / 删除数据(update 及 batchUpdate 方法)

  • 使用 Map 作为参数:通过int update(String sql, Map<String, ?> paramMap)方法,在Map中以键值对形式设置参数,键对应 SQL 语句中的命名参数,如:

Map<String, Object> paramMap = new HashMap<>();

paramMap.put("id", UUID.randomUUID().toString());

paramMap.put("name", "小明");

template.update(

    "insert into student(id,name) values (:id,:name)",

    paramMap

);

  • 使用 BeanPropertySqlParameterSource 作为参数:借助int update(String sql, SqlParameterSource paramSource),将 JavaBean 封装为BeanPropertySqlParameterSource传入,示例如下:

StudentDTO dto=new StudentDTO();

dto.setId(UUID.randomUUID().toString());

dto.setName("小红");

template.update("insert into student(id,name) values (:id,:name)",

                new BeanPropertySqlParameterSource(dto));

  • 使用 MapSqlParameterSource 作为参数:同样通过int update(String sql, SqlParameterSource paramSource),可链式调用addValue添加参数,或基于现有Map构建:

MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource()

       .addValue("id", UUID.randomUUID().toString())

       .addValue("name", "小王");

template.update("insert into student(id,name) values (:id,:name)",mapSqlParameterSource);

2. 查询数据(query 及 queryForXXX 方法)

  • 返回单行单列数据:有public < T > T queryForObject(String sql, Map<String, ?> paramMap, Class<T> requiredType)和public < T > T queryForObject(String sql, SqlParameterSource paramSource, Class<T> requiredType)两种形式,可传入Map、SqlParameterSource,如:

Integer count = template.queryForObject(

                "select count(*) from student", new HashMap<>(), Integer.class);

  • 返回(多行)单列数据:使用public < T> List< T> queryForList(String sql, Map<String, ?> paramMap, Class< T > elementType) 或public < T> List< T> queryForList(String sql, SqlParameterSource paramSource, Class< T> elementType) ,如:

List<String> namelist = template.queryForList("select name from student", new HashMap<>(), String.class);

  • 返回单行数据:public < T> T queryForObject(String sql, Map< String, ?> paramMap, RowMapper< T>rowMapper)和public < T> T queryForObject(String sql, SqlParameterSource paramSource, RowMapper< T> rowMapper) ,搭配RowMapper实现对象映射:

Student  stu = template.queryForObject(

                "select * from student limit 1", new HashMap<>(), new BeanPropertyRowMapper<Student>(Student.class));

  • 返回 Map 形式的单行数据:通过public Map< String, Object> queryForMap(String sql, Map< String, ?> paramMap)和public Map< String, Object> queryForMap(String sql, SqlParameterSource paramSource) ,将单行结果映射为Map 。
  • 返回多行数据:包括public < T> List< T> query(String sql, Map< String, ?> paramMap, RowMapper< T> rowMapper)等三个重载方法,根据需求传入参数和RowMapper;public List< Map< String, Object>> queryForList(String sql, Map< String, ?> paramMap) 等方法则返回多行数据的Map集合。

三、使用建议

在实际开发中,推荐优先使用NamedParameterJdbcTemplate替代JdbcTemplate 。若仍需使用JdbcTemplate,可通过NamedParameterJdbcTemplate#getJdbcOperations()获取。同时,由于查询结果为Map的 API 在数据类型处理上存在局限性,不建议频繁使用此类 API,以免后期维护成本增加。

以上详细介绍了NamedParameterJdbcTemplate的使用方法。若你在实践中遇到问题,或希望了解某类操作的更多细节,欢迎随时与我交流。

四、完整例子

import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;import org.springframework.jdbc.datasource.DriverManagerDataSource;import java.util.*;public class NamedParameterJdbcTemplateExample {private static NamedParameterJdbcTemplate template;static {// 配置数据源DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/test");dataSource.setUsername("root");dataSource.setPassword("password");// 初始化NamedParameterJdbcTemplatetemplate = new NamedParameterJdbcTemplate(dataSource);}public static void main(String[] args) {// 1. 插入数据 - 使用Map作为参数insertWithMap();// 2. 插入数据 - 使用BeanPropertySqlParameterSource作为参数insertWithBean();// 3. 查询单行单列数据Integer count = getCount();System.out.println("学生总数: " + count);// 4. 查询多行单列数据List<String> names = getNames();System.out.println("所有学生姓名: " + names);// 5. 查询单行数据Student student = getStudent();System.out.println("查询单个学生: " + student);// 6. 查询多行数据List<Student> students = getAllStudents();System.out.println("所有学生: " + students);// 7. 更新数据updateStudent();System.out.println("更新后所有学生: " + getAllStudents());// 8. 删除数据deleteStudent();System.out.println("删除后所有学生: " + getAllStudents());}// 1. 插入数据 - 使用Map作为参数private static void insertWithMap() {Map<String, Object> paramMap = new HashMap<>();paramMap.put("id", UUID.randomUUID().toString());paramMap.put("name", "小明");paramMap.put("age", 33);paramMap.put("homeAddress", "乐山");paramMap.put("birthday", new Date());template.update("insert into student(id,name,age,home_address,birthday) values (:id,:name,:age,:homeAddress,:birthday)",paramMap);}// 2. 插入数据 - 使用BeanPropertySqlParameterSource作为参数private static void insertWithBean() {StudentDTO dto = new StudentDTO();dto.setId(UUID.randomUUID().toString());dto.setName("小红");dto.setHomeAddress("成都");template.update("insert into student(id,name,home_address) values (:id,:name,:homeAddress)",new BeanPropertySqlParameterSource(dto));}// 3. 查询单行单列数据private static Integer getCount() {return template.queryForObject("select count(*) from student",new HashMap<>(),Integer.class);}// 4. 查询多行单列数据private static List<String> getNames() {return template.queryForList("select name from student",new HashMap<>(),String.class);}// 5. 查询单行数据private static Student getStudent() {return template.queryForObject("select * from student limit 1",new HashMap<>(),new BeanPropertyRowMapper<>(Student.class));}// 6. 查询多行数据private static List<Student> getAllStudents() {return template.query("select * from student",new BeanPropertyRowMapper<>(Student.class));}// 7. 更新数据private static void updateStudent() {MapSqlParameterSource params = new MapSqlParameterSource().addValue("age", 25).addValue("name", "小明");template.update("update student set age = :age where name = :name",params);}// 8. 删除数据private static void deleteStudent() {MapSqlParameterSource params = new MapSqlParameterSource().addValue("name", "小明");template.update("delete from student where name = :name",params);}// 学生DTO类public static class StudentDTO {private String id;private String name;private String homeAddress;// getter和setter方法public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getHomeAddress() {return homeAddress;}public void setHomeAddress(String homeAddress) {this.homeAddress = homeAddress;}}// 学生实体类public static class Student {private String id;private String name;private Integer age;private String homeAddress;private Date birthday;// getter和setter方法public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getHomeAddress() {return homeAddress;}public void setHomeAddress(String homeAddress) {this.homeAddress = homeAddress;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "Student{" +"id='" + id + '\'' +", name='" + name + '\'' +", age=" + age +", homeAddress='" + homeAddress + '\'' +", birthday=" + birthday +'}';}}}

相关文章:

NamedParameterJdbcTemplate 使用方法及介绍

NamedParameterJdbcTemplate是 Spring 框架中用于数据库操作的核心类之一&#xff0c;它拓展了JdbcTemplate&#xff0c;通过封装实现命名参数特性&#xff0c;相比传统占位符?&#xff0c;命名参数可读性和维护性更强&#xff0c;能有效避免参数顺序混淆问题。 一、核心支持…...

【web笔记】JavaScript实现有动画效果的进度条

文章目录 1 实现效果2 实现代码 1 实现效果 2 实现代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"utf-8"><style>#progress {width: 300px;height: 20px;border-radius: 0; /* 移除圆角 */-webkit-appearance…...

安装最新elasticsearch-8.18.2

1.环境我的环境是linux麒麟服务器 (安装 es 7.8以上 java环境必须11以上,可以单独配置es的java目录) 2.下载 官网的地址:下载 Elastic 产品 | Elastic Download Elasticsearch | Elastic Elasticsearch 入门 | Elasticsearch 中文文档 文档 3.我下载的是8.18的 Elasti…...

大数据学习(129)-Hive数据分析

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…...

React 进阶特性

1. ref ref 是 React 提供的一种机制,用于访问和操作 DOM 元素或 React 组件的实例。它可以用于获取某个 DOM 元素的引用,从而执行一些需要直接操作 DOM 的任务,例如手动设置焦点、选择文本或触发动画。 1.1. 使用 ref 的步骤 1. 创建一个 ref:使用 React.createRef 或 …...

Polarctf2025夏季赛 web java ez_check

第一次自己做出一个java&#xff0c;值得小小的记录&#xff0c;polar的java真得非常友好 反编译jar包&#xff0c;一眼就看到有个/deserialize 路由&#xff0c;接受base64的序列化数据&#xff0c;base64解码后 经过一次kmp检查&#xff0c;再由SafeObjectInputStream来反序列…...

vue3+el-table 利用插槽自定义数据样式

<el-table-column label"匹配度" prop"baseMatchingLevel"><template #default"scope"><div :style"{ color: scope.row.baseMatchingLevel > 0.8 ? #00B578 : #FA5151 }">{{ scope.row.baseMatchingLevel }}&l…...

跑通 TrackNet-Badminton-Tracking-tensorflow2 项目全记录

&#x1f4dd; 跑通 TrackNet-Badminton-Tracking-tensorflow2 项目全记录 git clone https://github.com/Chang-Chia-Chi/TrackNet-Badminton-Tracking-tensorflow2.git TrackNet-Badminton-Tracking-tensorflow2 conda create --prefix /cloud/TrackNet-Badminton-Tracking-…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(八)

uboot启动异常及解决 网络问题及解决 打开STM32CubeMX选中ETH1 - A7NS&#xff08;Linux&#xff09;Mode&#xff1a;RGMII&#xff08;Reduced GMII&#xff09;勾选ETH 125MHz Clock Input修改GPIO引脚如图所示 Net: No ethernet found.生成代码后&#xff0c;修改u-boot下…...

CodeBuddy一腾讯内部已有超过 85% 的程序员正在使用de编程工具

大家好&#xff0c;我是程序员500佰&#xff0c;目前正在前往独立开发路线&#xff0c;我会在这里分享关于编程技术、独立开发、技术资讯以及编程感悟等内容。 如果本文能给你提供启发和帮助&#xff0c;还请留下你的一健三连&#xff0c;给我一些鼓励&#xff0c;谢谢。 本文直…...

PHP 表单 - 验证邮件和URL

PHP 表单 - 验证邮件和URL 引言 在Web开发中&#xff0c;表单是用户与网站交互的重要途径。一个功能完善的表单不仅可以收集用户数据&#xff0c;还能提高用户体验。在表单设计中&#xff0c;验证邮件地址和URL是常见的需求。本文将详细介绍如何在PHP中实现邮件和URL的验证&a…...

leetcode238-除自身以外数组的乘积

leetcode 238 思路 可以在不使用除法的情况下&#xff0c;利用前缀积和后缀积来实现解答 前缀积&#xff1a;对每个位置&#xff0c;计算当前数字左侧的所有数字的乘积后缀积&#xff1a;对每个位置&#xff0c;计算当前数字右侧的所有数字的乘积 结合这两种思想&#xff0…...

论文阅读笔记——Large Language Models Are Zero-Shot Fuzzers

TitanFuzz 论文 深度学习库&#xff08;TensorFlow 和 Pytorch&#xff09;中的 bug 对下游任务系统是重要的&#xff0c;保障安全性和有效性。在深度学习&#xff08;DL&#xff09;库的模糊测试领域&#xff0c;直接生成满足输入语言(例如 Python )语法/语义和张量计算的DL A…...

matlab模糊控制实现路径规划

路径规划是机器人和自动驾驶系统中的重要问题之一&#xff0c;它涉及确定如何在给定环境中找到最优路径以达到特定目标。模糊控制是一种有效的控制方法&#xff0c;可以应用于路径规划问题。 路径规划算法的目标是在避免障碍物的情况下&#xff0c;找到机器人或车辆从起点到终…...

浅谈未来汽车电子电气架构发展趋势中的通信部分

目录 一、引入 1.1市场占比演化 1.2未来发展趋势 二、纯电动汽车与传统汽车的区别 2.1 纯电车和燃油车的架构&#xff08;干货&#xff09; 2.2 新能源汽车的分类 ⚡ 1. 纯电动汽车&#xff08;BEV&#xff09; &#x1f50b; 2. 插电式混合动力&#xff08;PHEV&#…...

基于 Transformer robert的情感分类任务实践总结之二——R-Drop

基于 Transformer robert的情感分类任务实践总结之一 核心改进点 1. R-Drop正则化 原理&#xff1a;通过在同一个输入上两次前向传播&#xff08;利用Dropout的随机性&#xff09;&#xff0c;强制模型对相同输入生成相似的输出分布&#xff0c;避免过拟合。实现&#xff1a…...

个人电脑部署本地大模型+UI

在这个AI飞速进步的时代&#xff0c;越来越多的大模型出现在市面上 本地大模型也越来越火爆&#xff01; 它完全免费&#xff0c;随时可以访问&#xff0c;数据仅存在本地&#xff0c;还可以自己微调&#xff0c;训练&#xff01; 今天我来教大家&#xff0c;如何在一台普通…...

Three.js + Vue3 加载GLB模型项目代码详解

本说明结合 src/App.vue 代码,详细解释如何在 Vue3 项目中用 three.js 加载并显示 glb 模型。 1. 依赖与插件导入 import {onMounted, onUnmounted } from vue import * as THREE from three import Stats from stats.js import {OrbitControls } from three/examples/jsm/co…...

MongoDB $type 操作符详解

MongoDB $type 操作符详解 引言 MongoDB 是一款流行的开源文档型数据库,它提供了丰富的查询操作符来满足不同的数据查询需求。在 MongoDB 中,$type 操作符是一个非常有用的查询操作符,它允许用户根据文档中字段的类型来查询文档。本文将详细介绍 MongoDB 的 $type 操作符,…...

Vue3项目实现WPS文件预览和内容回填功能

技术方案背景&#xff1a;根据项目需要&#xff0c;要实现在线查看、在线编辑文档&#xff0c;并且进行内容的快速回填&#xff0c;根据这一项目背景&#xff0c;最终采用WPS的API来实现&#xff0c;接下来我们一起来实现项目功能。 1.首先需要先准备好测试使用的文档&#xf…...

PySide6 GUI 学习笔记——常用类及控件使用方法(多行文本控件QTextEdit)

文章目录 PySide6.QtWidgets.QTextEdit 应用举例概述核心特性常用方法文本内容操作光标和选择操作格式和样式查找功能视图控制状态设置常用信号 代码示例示例说明1. 基本设置2. 文本格式化功能3. 功能按钮4. 信号处理 PySide6.QtWidgets.QTextEdit 应用举例 概述 QTextEdit 是…...

【版本控制】Git 和 GitHub 入门教程

目录 0 引言1 Git与GitHub的诞生1.1 Git&#xff1a;Linus的“两周奇迹”&#xff0c;拯救Linux内核1.2 GitHub&#xff1a;为Git插上协作的翅膀1.3 协同进化&#xff1a;从工具到生态的质变1.4 关键历程时间轴&#xff08;2005–2008&#xff09; 2 Git与GitHub入门指南2.1 Gi…...

上位机知识篇---Flask框架实现Web服务

本文将简单介绍Web 服务与前端显示部分&#xff0c;它们基于Flask 框架和HTML/CSS/JavaScript实现&#xff0c;主要负责将实时视频流和检测结果通过网页展示&#xff0c;并提供交互式状态监控。以下是详细技术解析&#xff1a; 一、Flask Web 服务架构 1. 核心路由设计 app.…...

django paramiko 跳转登录

在使用Django框架结合Paramiko进行SSH远程操作时&#xff0c;通常涉及到自动化脚本的执行&#xff0c;比如远程服务器上的命令执行、文件传输等。如果你的需求是“跳转登录”&#xff0c;即在登录远程服务器后&#xff0c;再通过该服务器的SSH连接跳转到另一台服务器&#xff0…...

Prompt工程学习之思维树(TOT)

思维树 定义&#xff1a;思维树&#xff08;Tree of Thoughts, ToT&#xff09; 是一种先进的推理框架&#xff0c;它通过同时探索多条推理路径对思维链&#xff08;Chain of Thought&#xff09;** 进行了扩展。该技术将问题解决视为一个搜索过程 —— 模型生成不同的中间步骤…...

基于python大数据的水文数据分析可视化系统

博主介绍&#xff1a;高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实实在…...

人工智能学习09-变量作用域

人工智能学习概述—快手视频 人工智能学习09-变量作用域—快手视频...

DJango知识-模型类

一.项目创建 在想要将项目创键的目录下,输入cmd (进入命令提示符)在cmd中输入:Django-admin startproject 项目名称 (创建项目)cd 项目名称 (进入项目)Django-admin startapp 程序名称 (创建程序)python manage.py runserver 8080 (运行程序)将弹出的网址复制到浏览器中…...

结构性-代理模式

动态代理主要是为了处理重复创建模板代码的场景。 使用示例 public interface MyInterface {String doSomething(); }public class MyInterfaceImpl implements MyInterface{Overridepublic String doSomething() {return "接口方法dosomething";} }public class M…...

【Redis】笔记|第10节|京东HotKey实现多级缓存架构

缓存架构 京东HotKey架构 代码结构 代码详情 功能点&#xff1a;&#xff08;如代码有错误&#xff0c;欢迎讨论纠正&#xff09; 多级缓存&#xff0c;先查HotKey缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新…...