Mybatis插入数据返回递增主键(Postgresql)

Return value of auto generating key after insert into one record

Posted by Xu Zhenxue on March 23, 2019

滚动阅读全文

一、数据库增加自增长字段

1、 PostgreSQL 数据库

方法一: 将自动增长字段设置为Serial类型,该字段会在数据插入后自动增长,Seria类型的字段,数据库会自动创建一个序列,序列名默认为:表名_字段名_seq。
方法二: 先创建序列名称,然后在新建表中为字段指定序列就可以了,该列需要int类型 创建序列的语法:

CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
    [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
    [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
    [ OWNED BY { table.column | NONE } ]

实例:

create sequence test_id_seq increment by 1 minvalue 1 no maxvalue start with 1;  
CREATE TABLE public.test
(
    id integer NOT NULL DEFAULT nextval('test_id_seq'::regclass),
    name character varying COLLATE pg_catalog."default"
)
2、MySQL数据库

在相应字段后增加 AUTO_INCEMENT
实例:

CREATE TABLE test
(
    id int(20) NOT NULL AUTO_INCEMENT,
    name char(20)
)

二、MyBatis插入数据并返回自增主键

方法一: 使用userGeneratedKeys

实例:

<insert id="saveAndGetId" parameterType="com.uniplore.etl.core.model.KettleJob" useGeneratedKeys="true" keyProperty="jobId">
        INSERT INTO kettle_job(
            job_name,
            job_desc,
            job_default_var,
            job_default_named_param,
            job_default_position_param
        )VALUES (
            #{jobName},
            #{jobDesc},
            #{jobDefaultVar},
            #{jobDefaultNamedParam},
            #{jobDefaultPositionParam}
        );
    </insert>

Tips:

  • useGeneratedKeys,这会令MyBatis使用JDBC的getGeneratedKeys方法获取由数据库内部生成的主键,默认为false,需要配合keyproperty属性使用。useGeneratedKeys="true" 表示给主键设置自增长
  • keyproperty,MyBatis会通过getGeneratedKeys的返回值设置它的键值。keyProperty="jobId" 表示自增长后的Id赋值给实体类的jobId字段
方法二、使用selectKey子元素

PostgreSQL数据库
实例:

<insert id="saveAndGetId" parameterType="com.uniplore.etl.core.model.KettleJob">
        <selectKey keyProperty="jobId" resultType="long" order="AFTER">
            SELECT currval('kettle_job_job_id_seq') AS jobId
        </selectKey>
        INSERT INTO kettle_job(
            job_name,
            job_desc,
            job_default_var,
            job_default_named_param,
            job_default_position_param
        )VALUES (
            #{jobName},
            #{jobDesc},
            #{jobDefaultVar},
            #{jobDefaultNamedParam},
            #{jobDefaultPositionParam}
        );
    </insert>

Tips:

  • keyProperty,selectKey语句结果应该被设置的目标属性
  • resultType,结果的类型
  • order,可以被设置为BEFORE或AFTER,如果设置为BEFORE,那么它会首先选择主键,设置keyProperty,先将结果赋值实体类,然后执行语句,如果设置为AFTER,那么先执行插入语句,然后是selectKey元素赋值实体类,。

PG数据库中nextval等函数的意义:

  • nextval(‘sequence_name’): 将当前值设置成递增后的值,并返回
  • currval(‘sequence_name’): 返回当前值
  • setval(‘sequence_name’, n, b=true): 设置当前值;b 默认设置 true,下一次调用 nextval() 时,直接返回 n,如果设置 false,则返回 n+increment:

这些函数仅适用于PG数据库,若使用其他数据库需要对函数进行替换。
MySQL数据库
实例:

<insert id="saveAndGetId" parameterType="com.uniplore.etl.core.model.KettleJob">
        <selectKey keyProperty="jobId" resultType="long" order="AFTER">
             SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO kettle_job(
            job_name,
            job_desc,
            job_default_var,
            job_default_named_param,
            job_default_position_param
        )VALUES (
            #{jobName},
            #{jobDesc},
            #{jobDefaultVar},
            #{jobDefaultNamedParam},
            #{jobDefaultPositionParam}
        );
    </insert>

以上两种方法,在插入实体后,通过实体的getId方法获取主键Id值。

方法三:RETURNING子句(仅适用于PG数据库)

实例:

<select id="test" parameterType="com.uniplore.etl.core.model.KettleJob" resultType="long">
        INSERT INTO kettle_job(
            job_name,
            job_desc,
            job_default_var,
            job_default_named_param,
            job_default_position_param
        )VALUES (
            #{jobName},
            #{jobDesc},
            #{jobDefaultVar},
            #{jobDefaultNamedParam},
            #{jobDefaultPositionParam}
        )RETURNING job_id;
    </select>

在PG数据库中RETURNING字句可以在数据插入后返回相应字段的值,类似于SELECT语句。 该方法获取查询的返回值获取Id