• MyBatis 返回insert操作主键


        应用场景 在向数据库插入数据时,需要保留插入数据的id,以便进行后续的update操作或者将id存入其他表作为外键。但是,在默认情况下,insert操作返回的是一个int值,它并非表示主键id,而是表示当前SQL语句影响的行数。

       接下来,我们依次从options注解和SQL两个方面,了解MyBatis如何在使用MySQL和Oracle做insert插入操作时将返回的id绑定到对象中。

    Mybatis的@Options注解

        mybatis的@Options注解能够拿到对象自增的id的值,能够设置缓存时间,首先,创建一张用于测试的表instance。

    复制代码
    CREATE TABLE instance (
      instance_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键id',
      infos VARCHAR(2048) NOT NULL DEFAULT '' COMMENT '消息',
      create_time datetime COMMENT '创建时间',
      update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      PRIMARY KEY (instance_id)
    )ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT '实例表';
    复制代码

        其中的instance_id是自增的主键。我希望通过dao层的接口插入的数据能够返回主键的id。接口代码如下:

    复制代码
    @Insert("insert into instance (infos)"
                        + " ("
                        + " @{infos},"
                        + " NOW()"
                        + ")")
        @Options(useGeneratedKeys = true, keyProperty = "instanceId", keyColumn = "instance_id")
        int addInstance(Instance instanceDto);
    复制代码

        @Options注解中默认设置的主键对应的字段名为id,而在instance表中,主键为instance_id,因此需要将keyProperty和keyColumn设置成我们想要的字段。这个示例的意思就是,从instance_id这个字段把数据放到传入对象instanceDto的instanceId成员变量里面。

        在调用了插入方法之后,@Options注解会自动为表的主键字段设置自增的值,并把它赋值给作为入参的DTO,进而可以直接从这个对象中获取新生成记录的主键。接下来看下@Option注解的源码:

    复制代码
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface Options {
        boolean useCache() default true;
        boolean flushCache() default false;
        ResultSetType resultSetType() default ResultSetType.FORWARD_ONLY;
        StatementType statementType() default StatementType.PREPARED;
        int fetchSize() default -1;
        int timeout() default -1;
        boolean useGeneratedKeys() default false;
        String keyProperty() default "id";
        String keyColumn() default "";
    }
    复制代码

        注解中的useCache还可以设置缓存相关的选项,useCache = true表示本次查询结果被缓存以提高下次查询速度,flushCache = false表示下次查询时不刷新缓存,timeout = 10000表示查询结果缓存10000秒。

        在文献[2]中,Java API àMapper Annotations中可以找到英文原版介绍。

    从执行insert SQL时返回主键ID

        MySQL用法:

    <insert id="insert" parameterType="com.test.Instance"  keyProperty=" instanceId" useGeneratedKeys="true" >

        上面配置中,“keyProperty”表示返回的instance_id要保存到对象的那个属性中,“useGeneratedKeys”表示主键为自增长模式。

        MySQL中做以上配置就OK了,较为简单,不再赘述。下面分享Oracle中的用法。

    复制代码
    <insert id="insert" parameterType="com.test.Instance ">
       <selectKey resultType="Long" order="BEFORE" keyProperty="instanceId">  
           SELECT SEQ_USER.NEXTVAL as instanceId from DUAL
       </selectKey> 
        insert into instance (instance_id, infos, create_time)
        values (#{instanceId}, #{infos}, now())
    </insert>
    复制代码

        Oracle用法中,需要注意的是:由于Oracle没有自增长一说法,只有序列这种模仿自增的形式,所以不能再使用“useGeneratedKeys”属性,而是使用<selectKey>将ID获取并赋值到对象的属性中,insert插入操作时正常插入id。

    参考文献

    [1] https://www.cnblogs.com/sonofelice/p/6250203.html.

    [2] http://www.mybatis.org/mybatis-3/index.html.

    原文地址:https://www.cnblogs.com/east7/p/10200872.html

  • 相关阅读:
    IM的扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理
    IM“扫一扫”功能很好做?看看微信“扫一扫识物”的完整技术实现
    2020年了,Android后台保活还有戏吗?看我如何优雅的实现!
    P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)
    微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结
    史上最通俗,彻底搞懂字符乱码问题的本质
    你知道,HTTPS用的是对称加密还是非对称加密?
    IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路
    面视必备,史上最通俗计算机网络分层详解
    阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处
  • 原文地址:https://www.cnblogs.com/jpfss/p/11629861.html
Copyright © 2020-2023  润新知