简体   繁体   中英

Is mybatis enable to insert all and return sequence(useGenerateKeys) in oracle?

I'm currently migrating from PostgreSQL to Oracle DBMS. but occur some problem. I wish to work "Insert all with sequence and return sequence to application using in mybatis."

My PostgreSQL Code is (it also works MySQL and MariaDB)

 <insert id="insertServiceCodeList" parameterType="serviceCodeVo" useGeneratedKeys="true" keyColumn="code" keyProperty="code">
    insert into service_code (
        serv_info_seq_id,
        name,
        default_key_type,
        cre_date,
        creator,
        description,
        state
    ) values 
    <foreach collection="list" item="item" separator=","> 
    (
        #{item.servInfoSeqId},
        #{item.name},
        #{item.defaultKeyType},
        now(),
        #{item.creator},
        #{item.description},
        0
    )
    </foreach>
</insert>

I tried to cases. see the below.

CASE 1

It does work in Oracle, But It does not work in mybatis, does not return sequence.

1.create sequnece

Create Sequence service_code_seq;

2.create function for sequence.nextval

create or replace function get_seq( seq_name in varchar2 ) 
return 
  number 
is
  v_num number;
  sql_stmt varchar2(64);
begin
  sql_stmt := 'select ' || seq_name || '.nextval from dual';
  execute immediate sql_stmt into v_num;
  return v_num;
end;

3.mybatis code for insert all

<insert id="insertServiceCodeList" parameterType="serviceCodeVo" useGeneratedKeys="true" keyColumn="code" keyProperty="code">
insert all
     <foreach collection="list" item="item" >
        into service_code (
            code,
            serv_info_seq_id,
            name,
            default_key_type,
            cre_date,
            creator,
            description,
            state
        ) values (
            get_seq( 'service_code_seq' ),
            #{item.servInfoSeqId},
            #{item.name},
            #{item.defaultKeyType},
            systimestamp,
            #{item.creator},
            #{item.description},
            0
        )
    </foreach>
    select * from dual;
</insert>

CASE 2

It does work in Oracle, But It does not work in mybatis, does not return sequence.

<insert id="insertServiceCodeList" parameterType="serviceCodeVo" useGeneratedKeys="true" keyColumn="code" keyProperty="code">
    insert into service_code (
        code,
        serv_info_seq_id,
        name,
        default_key_type,
        cre_date,
        creator,
        description,
        state
    ) select
        service_code_seq.nextval,
        servInfoSeqId,
        name,
        defaultKeyType,
        systimestamp,
        creator,
        description,
        0
    from (
    <foreach collection="list" item="item" separator="union all"> 
        select
            #{item.servInfoSeqId} servInfoSeqId,
            #{item.name} name,
            #{item.defaultKeyType} defaultKeyType,
            #{item.creator} creator,
            #{item.description} description
        from
            dual
    </foreach>
    )
</insert>

I wish to migrate from PostgreSQL to Oracle without modifying application code, migrate only SQL Code.

Thanks!!

It seems that returning generated keys from 'multi-row insert' is not supported by Oracle's driver.
So, it may not be possible "without modifying application code".

FYI, it may work if you switch to 'batch insert'.
It also performs better when inserting a lot of rows.

int batchSize = 1000;
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
  YourMapper mapper = sqlSession.getMapper(YourMapper.class);
  int size = serviceCodeList.size();
  for (int i = 0; i < size;) {
    mapper.insertServiceCode(serviceCodeList.get(i));
    i++;
    if (i % batchSize == 0 || i == size) {
      sqlSession.flushStatements();
      sqlSession.clearCache();
    }
  }
  sqlSession.commit();
}

The mapper statement is straightforward.

<insert id="insertServiceCode" useGeneratedKeys="true"
    keyColumn="code" keyProperty="code">
  insert into service_code (
    code,
    serv_info_seq_id,
    name,
    default_key_type,
    cre_date,
    creator,
    description,
    state
  ) values (
    service_code_seq.nextval,
    #{item.servInfoSeqId},
    #{item.name},
    #{item.defaultKeyType},
    systimestamp,
    #{item.creator},
    #{item.description},
    0
  )
</insert>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM