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

JdbcTemplate、NamedParameterJdbcTemplate 执行数据插入后返回主键写法

文章目录

  • 一、简单需求
  • 二、准备工作
  • 三、JdbcTemplate 实现
  • 四、NamedParameterJdbcTemplate 实现
  • 五、结论
  • 六、源码放送

一、简单需求

某业务操作,在执行数据保存后,需要查询具体的的数据信息,供二次确认。 从后台开发角度而言,转换成:插入1条数据库表记录后,如何返回当前插入数据的主键

二、准备工作

下面我们以JdbcTemplate、NamedParameterJdbcTemplate 为例来进行说明,为简单起见,我们以内存数据库H2
来进行演示。

首先,新建springboot工程,引入jdbc相关模块,在配置文件中引入数据源相关配置。

三、JdbcTemplate 实现


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.transaction.annotation.Transactional;import com.fly.template.bean.StudentVO;import lombok.extern.slf4j.Slf4j;@Slf4j
@Transactional
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
public class JdbcTemplateTest2
{@AutowiredJdbcTemplate jdbcTemplate;@BeforeEachpublic void init(){// execute可以执行所有SQL语句,因为没有返回值,一般用于执行DDL语句jdbcTemplate.execute("drop table if exists student");jdbcTemplate.execute("create table student(id bigint NOT NULL AUTO_INCREMENT, stu_name varchar(50), primary key(id))");jdbcTemplate.execute("insert into student(stu_name) values('Jack')");jdbcTemplate.execute("insert into student(stu_name) values('Phil')");jdbcTemplate.execute("insert into student(stu_name) values('Jenny')");// batchUpdatejdbcTemplate.batchUpdate("insert into student(stu_name) values(?)", Arrays.asList(new Object[][] {{"Tom"}, {"Jerry"}}));log.info("::: init success!!");log.info(">>>>> before: {}", jdbcTemplate.queryForObject("select count(*) from student", Long.class));}@AfterEachpublic void after(){log.info(">>>>> after : {}", jdbcTemplate.queryForObject("select count(*) from student", Long.class));}/*** 查询主键*/@Testpublic void testQueryPk(){KeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(new PreparedStatementCreator(){@Overridepublic PreparedStatement createPreparedStatement(Connection conn)throws SQLException{// 预处理,注意参数PreparedStatement.RETURN_GENERATED_KEYSPreparedStatement ps = conn.prepareStatement("insert into student(stu_name) values(?)", PreparedStatement.RETURN_GENERATED_KEYS);ps.setString(1, "Chery");return ps;}}, keyHolder);log.info("pk: {}", keyHolder.getKey().longValue());// lambda写法jdbcTemplate.update((conn) -> {PreparedStatement ps = conn.prepareStatement("insert into student(stu_name) values(?)", PreparedStatement.RETURN_GENERATED_KEYS);ps.setString(1, "Chery");return ps;}, keyHolder);log.info("pk: {}", keyHolder.getKey().longValue());}/*** 查询非自增主键*/@Testpublic void testQueryPk2(){jdbcTemplate.execute("drop table if exists student2");jdbcTemplate.execute("create table student2(id bigint NOT NULL, stu_name varchar(50), primary key(id))");KeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update((conn) -> {PreparedStatement ps = conn.prepareStatement("insert into student2(id, stu_name) values(?,?)", PreparedStatement.RETURN_GENERATED_KEYS);ps.setInt(1, 11);ps.setString(2, "Chery");return ps;}, keyHolder);log.info("pk: {}", keyHolder.getKey().longValue());}
}

四、NamedParameterJdbcTemplate 实现


import java.util.Arrays;
import java.util.Date;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.jdbc.core.JdbcOperations;
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.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.transaction.annotation.Transactional;import com.fly.template.bean.StudentVO;import lombok.extern.slf4j.Slf4j;@Slf4j
@Transactional
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
public class NamedJdbcTemplateTest
{@AutowiredNamedParameterJdbcTemplate namedJdbcTemplate;@BeforeEachpublic void init(){/****** JdbcOperations实际就是JdbcTemplate ******/JdbcOperations jdbcOperations = namedJdbcTemplate.getJdbcOperations();jdbcOperations.execute("drop table if exists student");jdbcOperations.execute("create table student(id int not null AUTO_INCREMENT, stu_name varchar(50), create_date datetime, primary key(id))");// batchUpdatejdbcOperations.batchUpdate("insert into student(stu_name, create_date) values(?, CURRENT_TIMESTAMP())", Arrays.asList(new Object[][] {{"Jack"}, {"Phil"}, {"Jenny"}}));jdbcOperations.execute("delete from student where id > 100");log.info("before::: init success!!");log.info(">>>>> before: {}", namedJdbcTemplate.getJdbcTemplate().queryForObject("select count(*) from student", Long.class));}@AfterEachpublic void after(){log.info(">>>>> after : {}", namedJdbcTemplate.getJdbcTemplate().queryForObject("select count(*) from student", Long.class));}@Testpublic void testQueryPk(){// 查询主键KeyHolder keyHolder = new GeneratedKeyHolder();namedJdbcTemplate.update("insert into student(stu_name, create_date) values(:stuName, :time)", new MapSqlParameterSource("stuName", "jackson").addValue("time", new Date()), keyHolder);log.info("pk: {}", keyHolder.getKey().longValue());namedJdbcTemplate.update("insert into student(stu_name, create_date) values(:stuName, :time)", new BeanPropertySqlParameterSource(new StudentVO().setStuName("jackson").setTime(new Date())), keyHolder);log.info("pk: {}", keyHolder.getKey().longValue());}
}

五、结论

从上面的实现过程可以看出,NamedParameterJdbcTemplate的实现方式更加简洁,言简意赅 ,建议采用!

六、源码放送

https://gitcode.com/00fly/springboot-demo/


有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-


http://www.mrgr.cn/news/81394.html

相关文章:

  • 活着就好20241224
  • uniApp打包H5发布到服务器(docker)
  • 操作系统(23)外存的存储空间的管理
  • 使用 ffmpeg 拼接合并视频文件
  • 【数据结构与算法】线性表——顺序储存与单链表
  • 探索多模态大语言模型(MLLMs)的推理能力
  • Pytorch | 利用I-FGSSM针对CIFAR10上的ResNet分类器进行对抗攻击
  • acme ssl证书自动续签 nginx
  • Android U 多任务启动分屏——system_server流程(更新中)
  • 【Linux】ChatGLM-4-9B模型之All Tools
  • 【目标跟踪综述及关键技术】
  • 重温设计模式--2、设计模式七大原则
  • 人工智能ACA(六)--计算机视觉基础
  • js版本之ES6特性简述【Proxy、Reflect、Iterator、Generator】(五)
  • 时钟芯片入门指南:从原理到实践
  • 消息队列(一)消息队列的工作流程
  • 【老白学 Java】HashMap 的基本使用
  • 项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”;每个机台各个管道的数据(温度、压力、气体)
  • 【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割
  • postman http请求正常,使用前端代理服务器报403
  • 使用Qwen2-VL模型批量标注图像内容(图像理解)
  • YOLOv11模型改进-模块-引入多尺度大核注意力Multi-scale Large Kernel Attention
  • 【阅读记录-章节6】Build a Large Language Model (From Scratch)
  • 机器学习2-NumPy
  • 使用RabbitMQ
  • ABAP开发-权限控制