返回主键值的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标签的执行顺序以及内层标签的返回值到底由谁来接收,可以看测试结果输出的底层内容
 
 
 - 在原先的insert标签中嵌套了selectKey标签(上文提到的特殊标签),关于该子标签的属性说明
 
测试代码
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
                                     
                    版权声明:程序员胖胖胖虎阿 发表于 2022年10月7日 下午2:00。
转载请注明:mybatis 08: 返回主键值的insert操作 + 利用UUID获取字符串(了解) | 胖虎的工具箱-编程导航
                    
            转载请注明:mybatis 08: 返回主键值的insert操作 + 利用UUID获取字符串(了解) | 胖虎的工具箱-编程导航
相关文章
暂无评论...
