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

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负责监控那一列的值自动填充了,并返回这一列的值让我们可以通过对象查询到

注意点:

唯一的注意点就是当我们需要区分我们具体是操作何种情况,合理的使用这两种方法返回的结果

http://www.lryc.cn/news/14414.html

相关文章:

  • sql语句练习
  • 广州蓝景—结合chatGPT下的教育模式变化
  • 大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——shuffle机制
  • 4|无线传感器网络与应用|无线传感器网络原理及方法-许毅版|第3章:无线传感器网络通信-3.1协议结构 3.2物理层|青岛科技大学|课堂笔记
  • 关机时,如何控制systemd服务的关闭顺序
  • 关于MySQL镜像构建过程中添加自动初始化数据库
  • CS144-Lab2
  • Linux内核驱动之efi-rtc
  • Java 字符串
  • 麦克风阵列波束基本概念理解
  • JAVA保姆式JDBC数据库免费教程之02-连接池技术
  • 视频片段怎么做成gif图?快试试这2种方法
  • 2.20计算机如何工作
  • [golang gin框架] 5.Cookie以及Session
  • 【牛客刷题专栏】0x0B:JZ3 数组中重复的数字(C语言编程题)
  • js中的隐式类型转换有哪些
  • WuThreat身份安全云-TVD每日漏洞情报-2023-02-17
  • 掌握MySQL分库分表(三)水平分库分表常见策略range、hash
  • CTFer成长之路之CTF中的SQL注入
  • python snap7读写PLC
  • 使用物联网进行智能能源管理的10大优势
  • 工业4.0和工业物联网如何协同工作
  • Python机器学习入门笔记(3)—— 线性回归
  • Java:顶级Java应用程序服务器 — Tomcat、Jetty、GlassFish、WildFly
  • 如何在SpringBoot项目上让接口返回数据脱敏,一个注解即可
  • python 之 海龟绘图(turtle)
  • RT-Thread SPI使用教程
  • shiro使用——整合spring
  • 2023-02-20 leetcode-AccountsMerge
  • 中国高速公路行业市场规模及未来发展趋势