Java

MyBatisで一括登録(バルクインサート)する方法

【MyBatis】BULK INSERTでデータを登録する方法

MyBatisでデータを一括登録(BULK INSERT)する方法を紹介します。

また「一括登録(BULK INSERT)」と「1件ずつ登録(INSERT)」する方法で 1万、10万、100万レコードを登録したときにかかる処理時間を測定しています。

本記事で使用するテーブル定義は次のとおり。

物理名 論理名 データ型 NOT NULL 説明
id ID BIGINT 主キー(AUTO_INCREMENT)
name 名前 VARCHAR(100) ユーザーの名前
address 住所 VARCHAR(255) ユーザーの住所
phone 電話番号 VARCHAR(50) ユーザーの電話番号
update_date 更新日時 DATETIME 最終更新日時
create_date 作成日時 DATETIME 登録日時
delete_date 削除日時 DATETIME 論理削除した日時

スポンサーリンク

SQL文(XMLファイル)

MyBatisのSQL文(XMLファイル)は次のとおり。通常のINSERT文と一括登録(BULK INSERT)のSQL文を記載しています。

[XMLファイル]

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserInfoMapper">

    <!-- 1件登録 -->
    <insert id="insert">
        INSERT INTO userInfo
        (
            name
            ,address
            ,phone
            ,update_date
            ,create_date
        )
        VALUES
        (
            #{name}
            ,#{address}
            ,#{phone}
            ,CURRENT_TIMESTAMP
            ,CURRENT_TIMESTAMP
        )
    </insert>

    <!-- 一括登録 -->
    <insert id="bulkInsert">
        INSERT INTO userInfo
        (
            name
            ,address
            ,phone
            ,update_date
            ,create_date
        )
        VALUES
        <foreach collection="userList" item="item" separator=",">
        (
            #{item.name}
            ,#{item.address}
            ,#{item.phone}
            ,CURRENT_TIMESTAMP
            ,CURRENT_TIMESTAMP
         )
        </foreach>
    </insert>

</mapper>

一括登録(BULK INSERT)は、<foreach>~</foreach>を利用し一括で登録する内容を生成しています。

Mapperクラス

MyBatisのMapperクラスは次のとおり。

[Mapperクラス]

package com.example.demo.dao;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.example.demo.entity.UserInfo;

/**
 * ユーザー情報 Mapper
 */
@Mapper
public interface UserInfoMapper {

    /**
     * ユーザー情報登録
     * @param userInfo ユーザー情報エンティティ
     */
    void insert(UserInfo userInfo);

    /**
     * ユーザー情報一括登録
     * @param userList ユーザー情報エンティティのリスト
     */
    void bulkInsert(List<UserInfo> userList);
}

測定結果

下記の表は「1件ずつ登録」した場合と「一括で登録(BULK INSERT)」した場合の測定結果です。

※測定しているPCのメモリは8GB、データベースはMySQLを使用、BULK INSERTは1000件単位で一括登録しています。

登録方法 1万件 10万件 100万件
1件ずつ登録 4秒 46秒 6分39秒
一括登録(1000件ずつまとめて登録) 2秒 7秒 1分19秒

測定した結果、1件ずつ登録するよりも一括で登録(BULK INSERT)した方が圧倒的に早いという結果になりました。

大量データを扱う場合は、BULK INSERTを使用することをお勧めします。