0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MySQL+MyBatisでシーケンス(連番)を扱う

Last updated at Posted at 2021-06-26

MySQLってシーケンスオブジェクトないんですね・・。auto_increment列使えよ〜ということなのかな?
軽くググってみると・・・LAST_INSERT_ID関数を使うとシーケンスっぽいことできるよ〜という記事がちらほら見つかりました。どうやら、この方法は公式のドキュメントでも紹介されている方法のようです。

検証バージョン

  • MySQL 8.0
  • MyBatis 3.5.6

テーブルを作る

create table sequence (
  name varchar(50) primary key,
  value   bigint
) ENGINE=MyISAM;

NOTE:

ENGINE=MyISAMにするとロールバックの影響を受けない(=ロールバックしても番号が戻らない)ようにすることができる見たいです(MyISAMがトランザクションをサポートしていないからのようです)。

Mapperを作る

@Mapper
public interface SequenceMapper {

  @Insert("INSERT INTO sequence (name, value) VALUES(#{name}, LAST_INSERT_ID(1)) " +
      "ON DUPLICATE KEY UPDATE value = LAST_INSERT_ID(value + 1)")
  @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "value", before = false, resultType = long.class)
  void incrementAndGet(Sequence sequence);

  default long nextSequence(String name) {
    Sequence sequence = new Sequence();
    sequence.name = name;
    incrementAndGet(sequence);
    return sequence.value;
  }

  class Sequence {
    private String name;
    private long value;
  }

}

シーケンス値を取得する

@SpringBootTest
class MyTest {

  @Autowired
  SequenceMapper sequenceMapper;

  @Test
  void test() {
    Assertions.assertThat(sequenceMapper.nextSequence("file_id")).isEqualTo(1L);
    Assertions.assertThat(sequenceMapper.nextSequence("file_id")).isEqualTo(2L);
    Assertions.assertThat(sequenceMapper.nextSequence("order_id")).isEqualTo(1L);
    Assertions.assertThat(sequenceMapper.nextSequence("order_id")).isEqualTo(2L);
  }

}

参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?