返回主键值的insert操作

应用背景

  • 图示说明

    • 在上述业务背景下,涉及两张数据表的关联操作:用户表 + 用户积分表
    • 传统操作:在对用户表执行完插入语句后,再次查询该用户的uid,将该uid作为外键,最后插入积分数据到用户积分表
      • 数据库操作次数:3次
    • 优化操作:在对用户表执行完插入语句后返回该用户的主键uid,将该uid作为外键,再插入用户积分数据到用户积分表
      • 数据库操作次数:2次
    • 优化操作可以减少对数据库的操作次数

代码实现

UsersMapper.java接口

package com.example.mapper;

import com.example.pojo.User;
import org.apache.ibatis.annotations.Param; import java.util.List; /**
* 数据访问层的接口,定义对数据库完成的CRUD的操作
*/
public interface UsersMapper { //插入用户数据并返回用户id
int insertAndReturnId(User user);
}
  • 接口代码说明

    • 方法中int类型的返回值并不是返回的用户id,而是插入操作执行后受影响的记录条数
    • 至于返回的用户id会通过特殊的sql标签中的属性来指定接收者
    • 后文中的映射文件会具体的介绍该特殊的sql标签及其属性,后文的测试输出结果中,也可以看到该特殊标签及其属性的底层作用原理
    • 在SqlMapConfig.xml核心配置文件中添加日志输出,方便查看sql标签的底层解析
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 设置日志输出--> <settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings> </configuration>

UsersMapper.xml映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.UsersMapper"> <!--
//插入用户数据并返回用户id
int insertAndReturnId(User user);
--> <insert id="insertAndReturnId" parameterType="user">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select
last_insert_id()
</selectKey>
insert into
users(username, birthday, sex, address)
values
(#{userName}, #{birthday}, #{sex}, #{address})
</insert>
</mapper>
  • 映射文件说明

    • 在原先的insert标签中嵌套了selectKey标签(上文提到的特殊标签),关于该子标签的属性说明

      • keyProperty属性:指明子标签的返回结果由入参中的哪个属性来接收
      • resultType属性:子标签的返回结果的类型
      • order属性:子标签相对于外层标签中的sql语句执行的先后顺序
    • last_insert_id():mysql内置的函数,返回插入的最后一条记录的自增主键id值
      • 关于sql标签的执行顺序以及内层标签的返回值到底由谁来接收,可以看测试结果输出的底层内容

测试代码

package com.example.mapper;

import com.example.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; public class TestUsersMapper { //时间刷
SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd"); //SqlSession对象
SqlSession sqlSession; //mybatis动态代理对象
UsersMapper usersMapper; //获取SqlSession
@Before
public void getSqlSession() throws IOException {
//读取核心配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//获取SqlSession
sqlSession = factory.openSession();
//获取mybatis动态代理对象
usersMapper = sqlSession.getMapper(UsersMapper.class);
} //归还SqlSession
@After
public void closeSession(){
sqlSession.close();
} @Test
public void testInsertAndReturnId() throws ParseException {
String dataStr = "1996-11-22";
User u = new User("小青", date.parse(dataStr), "女", "沈阳市");
int num = usersMapper.insertAndReturnId(u);
sqlSession.commit();
if(num == 1){
System.out.println("导入数据成功!");
}else{
System.out.println("导入数据失败!");
}
System.out.println("用户id: " + u.getId());
}
}

输出结果

Checking to see if class com.example.mapper.TestUsersMapper matches criteria [is assignable to Object]
Checking to see if class com.example.mapper.UsersMapper matches criteria [is assignable to Object]
Opening JDBC Connection
Created connection 295180183.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11981797] ==> Preparing: insert into users(username, birthday, sex, address) values (?, ?, ?, ?)
==> Parameters: 小青(String), 1996-11-22 00:00:00.0(Timestamp), 女(String), 沈阳市(String)
<== Updates: 1 ==> Preparing: select last_insert_id()
==> Parameters:
<== Columns: last_insert_id()
<== Row: 30
<== Total: 1 Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11981797] 导入数据成功!
用户id: 30 Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11981797]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11981797]
Returned connection 295180183 to pool. Process finished with exit code 0

测试结果分析

  • 由sql标签在底层的解析顺序以及解析后的内容可知

    • 在执行映射文件中的标签时,先执行的是selectKey标签外层标签中的sql语句,后执行的是子标签中的sql语句
//先
==> Preparing: insert into users(username, birthday, sex, address) values (?, ?, ?, ?)
==> Parameters: 小青(String), 1996-11-22 00:00:00.0(Timestamp), 女(String), 沈阳市(String)
<== Updates: 1
//后
==> Preparing: select last_insert_id()
==> Parameters:
<== Columns: last_insert_id()
<== Row: 30
<== Total: 1
  • 根据测试代码以及对应的输出结果可知

    • 接口文件中,方法中int类型的返回值并不是返回的用户id,而是插入操作执行后受影响的记录条数

    • keyProperty属性指明了子标签的返回结果(这里是用户id)由入参中的哪个属性来接收

//测试代码

int num = usersMapper.insertAndReturnId(u);
sqlSession.commit();
if(num == 1){
System.out.println("导入数据成功!");
}else{
System.out.println("导入数据失败!");
}
System.out.println("用户id: " + u.getId());
//对应输出结果

导入数据成功!

用户id: 30
  • 数据表中的结果

UUID

  • 由数字字母中划线组成的不重复的36位随机字符串
  • java和mysql对UUID都有支持
package com.example.mapper;

import java.util.UUID;

public class TestUsersMapper {

    @Test
public void testUUID(){
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
}
} /*
输出结果:
c5393056-6711-46c1-8134-80b83d2e9a76 Process finished with exit code 0
*/
select UUID();

--输出结果:13e622a2-1b0f-11ed-b2f9-0242ac110002

mybatis 08: 返回主键值的insert操作 + 利用UUID获取字符串(了解)的更多相关文章

  1. mybatis添加数据时返回主键 insert 返回主键值

    insert 返回主键值 useGeneratedKeys=“true” parameterType=“USer” keyProperty=“id”, <insert id="inse ...

  2. 深入浅出mybatis之返回主键ID

    目录 添加单一记录时返回主键ID 在映射器中配置获取记录主键值 获取新添加记录主键字段值 添加批量记录时返回主键ID 获取主键ID实现原理 添加记录后获取主键ID,这是一个很常见的需求,特别是在一次前 ...

  3. Mybatis批量insert 返回主键值和foreach标签详解

    Mybatis批量insert 返回主键 Mybatis从3.3.1版本开始,支持批量插入后返回主键ID.首先对于支持自增主键的数据库使用useGenerateKeys和keyProperty,对于不 ...

  4. Mybatis+Mysql 返回主键的值

    需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法:在mapper中指定keyProperty属性,示例如下: <insert id="i ...

  5. mybatis+mysql 返回主键

    需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法:在mapper中指定keyProperty属性,示例如下: <insert id="i ...

  6. Mybaits插入记录返回主键值

    某些情况进行insert时不知道主键值(主键为自增),例如系统新增用户时,有用户序号(主键 自增),用户名,密码.插入时只需插入用户名和密码,之后取得mysql自增的序号. 如下为mysql的usr表 ...

  7. mybatis insertUseGeneratedKeys 返回主键为null

    package tk.mybatis.mapper.common.special; import org.apache.ibatis.annotations.InsertProvider; impor ...

  8. MyBatis插入语句返回主键值

    插入语句xml代码: <insert id="insertUser" parameterType="com.spring.mybatis.po.User" ...

  9. 使用mybatis注解@Options实现添加记录时返回主键值

    官网:http://www.mybatis.org/mybatis-3/index.html 在使用mybatis作为ORM框架时,我通常更喜欢使用注解而非xml配置文件的方式.业务场景:添加记录之后 ...

随机推荐

  1. CF1682C. LIS or Reverse LIS?

    题意:给\(n\)个数,问你能构出严格上升子序列长度和下降子序列长度最小值的最大值. 思路: 如果一个数出现至少两次,ans++. 统计出现一次的个数,因为再最长上升子序列中,只能有一个值能贡献到下降 ...

  2. CSS中html的标签元素分类

    在CSS中,html中的标签元素大体被分为三种不同的类型: 块状元素.内联元素(又叫行内元素)和内联块状元素.    常用的块状元素有:  <div>.<p>.<h1&g ...

  3. net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos

    1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...

  4. jenkins 自动化部署vue前端+java后端项目 进阶一

    今天又不想写了,那么我来将我参考的文章直接分享给大家好了,大家也可以直接进行参考: 这里以centos7为例搭建自动化部署项目: 1.搭建部署前端服务代理nginx: 借鉴于:https://blog ...

  5. AtCoder ABC 242 题解

    AtCoder ABC 242 题解 A T-shirt 排名前 \(A\) 可得 T-shirt 排名 \([A+1,B]\) 中随机选 \(C\) 个得 T-shirt 给出排名 \(X\) ,求 ...

  6. 技术分享 | app自动化测试(Android)--App 控件定位

    原文链接 客户端的页面通过 XML 来实现 UI 的布局,页面的 UI 布局作为一个树形结构,而树叶被定义为节点.这里的节点也就对应了要定位的元素,节点的上级节点,定义了元素的布局结构.在 XML 布 ...

  7. 【RocketMQ】NameServer的启动

    NameServer是一个注册中心,Broker在启动时向所有的NameServer注册,生产者Producer和消费者Consumer可以从NameServer中获取所有注册的Broker列表,并从 ...

  8. re学习笔记

    re学习笔记 学习链接: https://regexlearn.com/zh-cn/learn \w: 数字字母下划线 \W: 非\w \d \D: !\d \s: space cha \S: !\s ...

  9. 19.Tomcat多实例部署及负载均衡、动静分离

    Tomcat多实例部署及负载均衡.动静分离 目录 Tomcat多实例部署及负载均衡.动静分离 Tomcat多实例部署 安装jdk 设置jdk环境变量 安装tomcat 配置 tomcat 环境变量 修 ...

  10. go-zero微服务实战系列(五、缓存代码怎么写)

    缓存是高并发服务的基础,毫不夸张的说没有缓存高并发服务就无从谈起.本项目缓存使用Redis,Redis是目前主流的缓存数据库,支持丰富的数据类型,其中集合类型的底层主要依赖:整数数组.双向链表.哈希表 ...