JavaEE简单示例——再插入的同时获取插入的主键列
简单介绍:
在某些时候,我们在插入完成一条语句之后,我们会想要返回之前插入的这条语句的主键列的数据,进行下一步的展示或者修改,我们就可以使用MyBatis的主键回写功能,帮助我们获取插入成功的一条数据的主键列。不同的数据库获取主键列的方式不同,主要针对两种情况:一种是主键支持自增的情况,一种是主键不支持自增的情况。我们会针对这两种情况分别进行说明。
前期准备:
在数据库方面,我们需要准备一个数据库,并在里面提前存放一些数据:

注意这里我们并没有设置主键,我们先演示没有主键或主键不支持自增的时候的情况,之后再添加主键演示当支持主键自增时候的情况。然后就是MyBatis环境的基本准备,如果之前有一个可以运行的MyBatis的基础环境这一步就可以省略了。
实现原理:
如果这个表支持主键自增的情况,在我们使用<insert>进行插入的时候,可以使用几个特殊的属性:
keyProperty:这个属性用来设置返回的主键复制给POJO实体类的那一个属性。
keyColumn:这个属性用来设置第几列是主键,当主键不是数据表中的第一列的时候需要设置。
useGeneratedKeys:该属性会使MyBatis调用JDBC的getGeneratedKeys()方法来获取由数据库内部生产的主键,比如MySQL中的自动递增的字段,默认值使false。说人话就是MySQL支持逐渐自增,也就是说如果这个表里有一个列自增了,那么这个自增的列就是主键。因为在MySQL中只有主键是支持自增的,其他的列不会自增,所以MyBatis就会捕捉到这个现象,并将自增的数据返回到我们的POJO实体类中,这样就可以获取到这个自增的主键列。
但是当这个表中的主键不支持自增的时候,就需要使用特殊的规则获取我们插入的主键,或者我们自定义规则插入一个主键然后获取,这时候就需要我们的另一个标签:selectKey
这个标签用来配置我们的主键规则,因为在有些时候,我们不会插入主键,但是主键是必须的,所以我们会设定一个规则来帮助我们在没有主键自增长的时候还能自动插入主键:
这个标签有几个常用的属性:
keyProperty,resultType,order,statementType。其中其他几个属性的作用和上面的一样,order属性的值有两个:BAFORE和AFTER。BEFORE表示在执行插入语句之前先执行selectKey中配置的SQL语句,一般用于无法手动插入主键的时候使用。AFTER表示在插入语句之后再执行selectKey中配置的SQL语句,一般用于手动插入主键时使用。
1.当数据库的主键不支持自动增长或者主键没有设置自动增长的时候:
代码实现:
我们首先来看当不支持主键自增的时候我们如何使用Java代码帮助我们自动插入主键:
SQL语句映射文件:
<!-- 测试主键回写--><insert id="insertAuto" parameterType="student"><selectKey keyProperty="id" order="BEFORE" resultType="Integer">
# 设置自动添加主键的规则,表示当主键列的最大值为空,表示这是第一条数据的时候,返回1,如果这条主键列最大的值不是null,则返回最大的值再加一
# 使用这种方法也可以达到主键自增的效果select if(max(id) is null ,1,max(id) + 1) as idNum from student;</selectKey>insert into student values (#{id},#{name},#{password});</insert>
接口映射文件:
package Mappers;
import com.mybatis.POJO.student;
import com.mybatis.POJO.user;import java.util.List;public interface select {public student selectOne(int i);public List<student> selectAll();public student selectName();public void insertInto(student s);public int deleteOne(int i);public void insertAuto(student s);
}
测试类:
package Mappers;import com.mybatis.POJO.Tools.createSqlSession;
import com.mybatis.POJO.student;
import org.apache.ibatis.session.SqlSession;public class TestInsertAuto {select mapper = null;SqlSession session = null;@org.junit.Testpublic void insertNotAuto(){
// 使用工具类获取连接mapper = new createSqlSession().createMapper();
// 测试接口中映射的方法
// 创建插入表中的对应的POJO类的对象
// 注意我们并不设置主键列也就是id的值,主要是为了查看能否达到自动填充并增加的效果student s = new student();s.setName("赵六");s.setPassword("1234556");mapper.insertAuto(s);
// 遍历数据库中的数据for (student student : mapper.selectAll()) {System.out.println(student);}
// 然后我们再获取一次看能不能获取的对象的id的值System.out.println("插入的数据的id值是:"+s.getId());}
}
运行结果:

可以看到,在我们没有设置id的值的时候,我们依然完成了主键的自增和获取,这就说明我们之前的配置是正确的。
注意点:
整个的运行流程是当我们插入一条数据的时候,因为我们selectKey的order属性配置的是BEFORE,所以我们首先会执行selectKey中的语句,然后他会判断我们数据表的主键列是否有数据,如果有数据,则获取最大的数据加一得到一个新的数据。这个过程就是我们在selectKey中配置的SQL语句来帮我们完成的。然后selectKey的另外两个属性,keyProperty的值表示将得到的数据插入到POJO实体类的哪一个属性中,resultType的值表示这个值的类型。然后执行insert标签中的SQL语句,最后将数据插入完成之后,会将我们刚才设置的值返回给student类,我们就可以通过getId的方法得到我们刚才自动生成的值。
需要注意的是我们要明确selectKey中配置的SQL语句是帮助我们自动生成主键的值的,这个值会被复制给POJO类的id属性。然后就是SQL语句中的if语句的使用方法。
1.当数据库的主键支持自动增长并且设置了自动增长的时候:
实现原理:
当主键设置了自动增长的时候,就不需要我们手动填充主键,MyBatis会自动的帮我们去检测某一列的值是否自动增加了,如果在我们没有填充的情况下自动填充了,那么这个列就是主键,MyBatis会自动帮我们把填充后的值获取到,我们只需要正确的配置即可。
代码实现:
SQL映射文件:
<!-- 当支持主键自增时候的主键回写--><insert id="insertAuto" parameterType="student" keyProperty="id" useGeneratedKeys="true">insert into student values (#{id},#{name},#{password});</insert>
接口文件:
package Mappers;
import com.mybatis.POJO.student;
import com.mybatis.POJO.user;import java.util.List;public interface select {public student selectOne(int i);public List<student> selectAll();public student selectName();public void insertInto(student s);public int deleteOne(int i);public void insertNotAuto(student s);public void insertIntoAuto(student s);
}
测试类:
@org.junit.Testpublic void insertIntoAuto(){// 使用工具类获取连接mapper = new createSqlSession().createMapper();
// 测试接口中映射的方法,这次测试的是带有主键自增的数据表student s = new student();s.setName("赵六");s.setPassword("1234556");mapper.insertIntoAuto(s);
// 遍历数据库中的数据for (student student : mapper.selectAll()) {System.out.println(student);}
// 然后我们再获取一次看能不能获取的对象的id的值System.out.println("插入的数据的id值是:"+s.getId());}
运行结果:

可以看到,在我们没有设置id主键值的时候,自动填充主键值的操作是由数据库完成的,而MyBatis负责监控那一列的值自动填充了,并返回这一列的值让我们可以通过对象查询到
注意点:
唯一的注意点就是当我们需要区分我们具体是操作何种情况,合理的使用这两种方法返回的结果
相关文章:
JavaEE简单示例——再插入的同时获取插入的主键列
简单介绍: 在某些时候,我们在插入完成一条语句之后,我们会想要返回之前插入的这条语句的主键列的数据,进行下一步的展示或者修改,我们就可以使用MyBatis的主键回写功能,帮助我们获取插入成功的一条数据的主…...
sql语句练习
一、现有以下两张表:第一张表名为cust,其表结构如下:第二张表名为mark,其表结构如下:1) [5分]请写出计算 所有学生的英语平均成绩的sq|语句。2) [5分]现有五 个学生,其学号假定分别为11,22,33,44,55;请用一条SQL语句实现列出这五个…...
广州蓝景—结合chatGPT下的教育模式变化
最近爆火的人工智能AI聊天工具ChatGPT,不仅在互联网,更是在各行各业中,得到了广泛的传播,应该没有哪一个不知道它的存在,但其实你又是否知道,其实ChatGPT是一类模型的统称,随着人工智能的快速发…...
大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——shuffle机制
3.3.1Shuffle机制 Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle。 3.3.2Partition分区 1、问题引出 要求将统计结果按照条件输出到不同文件中(分区)。比如:将统计结果按照手机归属地不同省份输出到不同文件中&#…...
4|无线传感器网络与应用|无线传感器网络原理及方法-许毅版|第3章:无线传感器网络通信-3.1协议结构 3.2物理层|青岛科技大学|课堂笔记
第3章:无线传感器网络通信3.1协议结构3.1.1 OSI参考模型1.网络通信协议MAC层和物理层采用IEEE 802.15.4协议*(1)物理层wsn物理层负责信号的调制和数据的收发,传输介质:无线电、红外线、光波等。(2)数据链路层wsn数据链路层负责数据成帧、帧检…...
关机时,如何控制systemd服务的关闭顺序
关机时,如何控制systemd服务的关闭顺序? 在工作中,我们通常遇到的问题是,如何控制systemd服务的启动顺序,同志们第一反应就会是使用Before或者After去进行控制。 问题来了,如果服务启动时没有顺序要求,但…...
关于MySQL镜像构建过程中添加自动初始化数据库
需求描述一般而言,我们在拉取了 mysql 镜像并运行之后,其中的并不会存在我们自定义的数据库,都是在镜像运行后,自己主动导入数据库,那么有没有方式可以一运行 mysql 镜像,对应生成的 mysql 容器中就有我们自…...
CS144-Lab2
实验架构 除了写入传入流之外,TCPReceiver 还负责通知 sender 两件事: “First unassembled” 字节的索引,称为“acknowledgment”或 “ackno”。这是接收方需要来自发送方的第一个字节。“first unassembled ” 索引和“first unacceptable…...
Linux内核驱动之efi-rtc
Linux内核驱动之efi-rtc1. UEFI与BIOS概述1.1. BIOS 概述1.1.1. BIOS缺点:1.1.2. BIOS的启动流程1.2 UEFI 概述1.2.1 Boot Sevices:1.2.2. Runtime Service:1.2.3. UEFI优点:1.2.4. UEFI启动过程:1.3 Legacy和UEFI1.4 …...
Java 字符串
文章目录一、API二、String1. String 构造方法2. String 对象的特点3. 字符串的比较4. 用户登录案例5. 遍历字符串6. 统计字符次数7. 拼接字符串8. 字符串反转三、StringBuilder1. 构造方法2. 添加及反转方法3. 与 String 相互转换4. 拼接字符串升级版5. 字符串反转升级版一、A…...
麦克风阵列波束基本概念理解
波束形成 本质上是设计合适的滤波器,对于一类固定滤波器系数的阵列来说,无论输入信号或者噪声信号的统计特征如何,其滤波器系数固定不变,此类波束形成叫Fixed Beamforming,固定波束形成好比传统数字信号处理里面的经典…...
JAVA保姆式JDBC数据库免费教程之02-连接池技术
连接池 连接池概念 概念:其实就是一个容器(集合),存放数据库连接的容器。 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完…...
视频片段怎么做成gif图?快试试这2种方法
动态gif图片作为当下非常常用的表情包,其丰富的内容生动的画面深受大众喜爱。那么,当我们想要将电影或是电视剧中的某一片段做成gif动态图片的时候,要如何操作呢?接下来,给大家分享两招视频转化gif的小窍门–使用【GIF…...
2.20计算机如何工作
一.计算机组成1.冯诺依曼体系CPU 中央处理器: 进行算术运算和逻辑判断.存储器: 分为外存和内存, 用于存储数据(使用二进制方式存储)输入设备: 用户给计算机发号施令的设备.输出设备: 计算机个用户汇报结果的设备内存和外存的区别(面试)访问速度:内存快,外存慢存储空间:内存小,外…...
[golang gin框架] 5.Cookie以及Session
1.Cookie(1).介绍HTTP 是无状态协议,简单地说,当浏览了一个页面,然后转到同一个网站的另一个页面,服务器无法认识到这是同一个浏览器在访问同一个网站,每一次的访问,都是没有任何关系的,如果要实现多个页面之间共享数据的话就可以…...
【牛客刷题专栏】0x0B:JZ3 数组中重复的数字(C语言编程题)
前言 个人推荐在牛客网刷题(点击可以跳转),它登陆后会保存刷题记录进度,重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏:个人CSDN牛客刷题专栏。 题目来自:牛客/题库 / 在线编程 / 剑指offer: 目录前言问题…...
js中的隐式类型转换有哪些
目录一、隐式类型转换条件二、 的隐式类型转换三、 的隐式类型转换四、object 的隐式类型转换探讨 object 的隐式转换执行顺序探讨 Symbol.toPrimitive 属性如何将对象转换为原始值在前端js这门动态弱类型语言中,不仅存在着显示类型转换,还存在许多隐式类…...
WuThreat身份安全云-TVD每日漏洞情报-2023-02-17
漏洞名称:IBM Aspera Faspex 预身份验证 RCE 漏洞 漏洞级别:高危 漏洞编号:CVE-2022-47986 相关涉及:IBM Aspera Faspex 漏洞状态:POC 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-02805 漏洞名称:Kardex Mlog MCC PATH 遍历 漏洞级别:严重 漏洞编号:CVE…...
掌握MySQL分库分表(三)水平分库分表常见策略range、hash
文章目录range策略Range策略延伸基于Range范围分库分表业务场景hash取模案例规则水平分库分表,根据什么规则进行划分? range策略 自增id,根据ID范围进行分表(左闭右开) 规则案例: 1~1,000,000 是 table…...
CTFer成长之路之CTF中的SQL注入
CTF中的SQL注入CTF SQL注入 SQL注入-1 题目描述: 暂无 docker-compose.yml version: 3.2services:web:image: registry.cn-hangzhou.aliyuncs.com/n1book/web-sql-1:latestports:- 80:80启动方式 docker-compose up -d 题目Flag n1book{union_select_is_so_cool} Wri…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
