mybatis学习笔记(七):主键返回

背景

在企业开发中,需要获取新插入到数据库中的记录主键作为业务逻辑的一部分,那么如何获取相应的主键,是这篇博客的出发点。

上一篇博客mybatis学习笔记(六):添加用户信息中相关的配置和代码,大家注意的话有看到有一行打印获取主键的代码:

System.out.println(user.getId());

控制台中打印出来的结果为:0,事实上在数据库中插入的记录的id是一个自增id,不是0,所以如何不做一些其他配置的话,通过user.getId()是无法获取到正确的主键信息

主键类型

主键类型分为两种:

  • 自增主键

  • 非自增主键

自增主键返回

mysql自增主键,执行insert提交之前自动生成一个自增主键。可以通过mysql自带函数LAST_INSERT_ID()获取刚插入记录的自增主键。此函数是在insert之后调用此函数

映射文件

在User.xml中配置添加用户的statement

添加内容如下:

    <!-- 添加增用户
     parameterType:指定输入参数类型为pojo,即用户信息
     ${}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
     用户信息表user的id是自增主键,在sql语句中不需要写上id字段及对应的属性值
     -->
    <insert id="insertUser" parameterType="com.trc.qa.po.User">

        <!--
         将插入数据的主键返回,返回到User对象中。
         keyProperty:将查询到的主键值设置到parameterType指定的对象的哪个属性
         order:select last_insert_id()执行顺序,相对于insert语句来说的执行顺序,这里设置的是AFTER
         resultType:指定select last_insert_id()的结果类型
         select last_insert_id():得到刚insert进去记录的主键值,此方法只适用于自增主键
         -->
        <selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
            select last_insert_id()
        </selectKey>
        INSERT INTO user (username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
    </insert>

程序代码

参考上一篇博客mybatis学习笔记(六):添加用户信息,这里就不重复粘贴了

程序执行结果

......

[DEBUG]15:54:12,725,main,[Class]JdbcTransaction, [Method]openConnection, Opening JDBC Connection
[DEBUG]15:54:13,019,main,[Class]PooledDataSource, [Method]popConnection, Created connection 1630521067.
[DEBUG]15:54:13,020,main,[Class]JdbcTransaction, [Method]setDesiredAutoCommit, Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]
[DEBUG]15:54:13,021,main,[Class]insertUser, [Method]debug, ==>  Preparing: INSERT INTO user (username,birthday,sex,address) VALUES(?,?,?,?) 
[DEBUG]15:54:13,075,main,[Class]insertUser, [Method]debug, ==> Parameters: 王大锤(String), 2018-07-25 15:54:12.721(Timestamp), 1(String), 河南洛阳(String)
[DEBUG]15:54:13,079,main,[Class]insertUser, [Method]debug, <==    Updates: 1
[DEBUG]15:54:13,081,main,[Class]insertUser!selectKey, [Method]debug, ==>  Preparing: select last_insert_id() 
[DEBUG]15:54:13,081,main,[Class]insertUser!selectKey, [Method]debug, ==> Parameters: 
[DEBUG]15:54:13,104,main,[Class]insertUser!selectKey, [Method]debug, <==      Total: 1
[DEBUG]15:54:13,105,main,[Class]JdbcTransaction, [Method]commit, Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]
17
[DEBUG]15:54:13,106,main,[Class]JdbcTransaction, [Method]resetAutoCommit, Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]
[DEBUG]15:54:13,107,main,[Class]JdbcTransaction, [Method]close, Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]

......

可以看到获取用户信息主键ID的值为17,跟数据库插入的记录中id的值一致

这里介绍完自增主键的使用方法之后,再介绍一下非自增主键返回如何使用

非自增主键返回(使用uuid())

使用mysql的uuid()自带函数生成主键,需要修改表中id字段类型为String,长度设置为64位。

执行思路:

先通过uuid()查询到主键,将主键输入到sql语句中

执行uuid()语句顺序相当于insert语句执行之前

创建用户信息表user_new

由于字段id不是自增主键,对应的数据类型不再是int类型,需要调整为varchar类型,为了便于后续博客的介绍,不直接修改user表,而新建一张表user_new,对应建表sql语句如下:

CREATE TABLE `user_new` (
  `id` varchar(64) NOT NULL,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(255) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

创建用户信息UserNew的pojo

由于字段id不是自增主键,对应的数据类型不再是int类型,需要调整为varchar类型,为了便于后续博客的介绍,不直接修改之前的User pojo,新建一个UserNew,对应代码如下:

public class UserNew {

    private String id;
    private String username; //用户姓名
    private String sex; //性别
    private Date birthday; //生日
    private String address; //地址

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

映射文件

在User.xml中配置对应的statement,内容如下:

    <!-- 新增用户 user_new -->
    <insert id="insertUserNew" parameterType="com.trc.qa.po.UserNew">

        <!--
         使用mysql的uuid()生成主键,相对于insert语句来说的执行顺序,这里设置的是BEFORE
         执行过程:
         首先通过uuid()生成主键,将主键设置到UserNew对象的id属性中,
         其次在insert执行时,从user对象中取出id属性值
         -->
        <selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
            select uuid()
        </selectKey>
        INSERT INTO user_new (id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
    </insert>

程序代码

    //添加用户信息
    @Test
    public void insertUserNewTest() throws IOException {

        String resource = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserNew user = new UserNew();
        user.setUsername("张大锤");
        user.setBirthday(new Date());
        user.setSex("0");
        user.setAddress("西安兵马俑");

        sqlSession.insert("test.insertUserNew", user);

        //提交事务
        sqlSession.commit();

        //获取用户信息主键
        System.out.println(user.getId());

        sqlSession.close();
    }

程序执行结果

......

[DEBUG]16:43:43,680,main,[Class]JdbcTransaction, [Method]openConnection, Opening JDBC Connection
[DEBUG]16:43:43,955,main,[Class]PooledDataSource, [Method]popConnection, Created connection 1226622409.
[DEBUG]16:43:43,955,main,[Class]JdbcTransaction, [Method]setDesiredAutoCommit, Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@491cc5c9]
[DEBUG]16:43:43,958,main,[Class]insertUserNew!selectKey, [Method]debug, ==>  Preparing: select uuid() 
[DEBUG]16:43:44,001,main,[Class]insertUserNew!selectKey, [Method]debug, ==> Parameters: 
[DEBUG]16:43:44,028,main,[Class]insertUserNew!selectKey, [Method]debug, <==      Total: 1
[DEBUG]16:43:44,028,main,[Class]insertUserNew, [Method]debug, ==>  Preparing: INSERT INTO user_new (id,username,birthday,sex,address) VALUES(?,?,?,?,?) 
[DEBUG]16:43:44,036,main,[Class]insertUserNew, [Method]debug, ==> Parameters: d693867c-8fe6-11e8-b7f4-7439c01734bf(String), 张大锤(String), 2018-07-25 16:43:43.674(Timestamp), 0(String), 西安兵马俑(String)
[DEBUG]16:43:44,037,main,[Class]insertUserNew, [Method]debug, <==    Updates: 1
[DEBUG]16:43:44,037,main,[Class]JdbcTransaction, [Method]commit, Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@491cc5c9]
d693867c-8fe6-11e8-b7f4-7439c01734bf
[DEBUG]16:43:44,038,main,[Class]JdbcTransaction, [Method]resetAutoCommit, Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@491cc5c9]
[DEBUG]16:43:44,039,main,[Class]JdbcTransaction, [Method]close, Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@491cc5c9]

......

对应的主键id成功返回,跟数据库插入记录的主键id一致

猜你喜欢

转载自blog.csdn.net/kuangay/article/details/81205856