概要
- Listのデータをinsertしたいときに1件ずつinsertするのは無駄なのでデータをまとめて一括でinsertしたい
- MyBatisGeneratorで自動生成されたMapperをカスタマイズした
注意事項
- 再びgenerateしたら上書きされて消えるので要注意
- IDがAUTO INCREMENTの場合はやり方が違うらしい
環境
- Java8
- SpringBoot v2.0.6.RELEASE
- mybatis-spring-boot-starter v1.3.2
- MySQL v5.7.25
方法
やることは2つ。
- Mapperクラスに一括insertメソッドを定義する
- xmlに一括insertの設定を追加する
例
例えばこんなテーブル(MySQL)があったとする。
user_friend.sql
CREATE TABLE user_friend (
user_id int(10) NOT NULL,
friend_id int(10) NOT NULL
friend_name varchar(30) NOT NULL,
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
PRIMARY KEY (user_id, friend_id)
);
Mapperクラスにメソッドを追加する
- insertBulkのメソッドを追加する
- 引数にinsertしたいデータのListを渡す
-
@Param
で名前を付けるかどうかは任意
UserFriendMapper.java
int insertBulk(@Param("friendList")List<UserFriend> friendList);
xmlに設定を追加する
-
UserFriendMapper.xml
にinsert id="insertBulk"
を追加する-
parameterType="java.util.List"
に指定する - Mapperで
@Param
を指定しなかった場合はcollection="list"
と指定する
-
UserFriendMapper.xml
<!-- これを追加する -->
<insert id="insertBulk" parameterType="java.util.List">
insert into user_friend
(user_id, friend_id, friend_name, created_at, updated_at)
values
<foreach collection="friendList" item="fr" separator=",">
(
#{fr.userId,jdbcType=INTEGER}, #{fr.friendId,jdbcType=INTEGER},
#{fr.friendName,jdbcType=VARCHAR}, #{fr.createdAt,jdbcType=TIMESTAMP},
#{fr.updatedAt,jdbcType=TIMESTAMP}
)
</foreach>
</insert>
Java(SpringBoot)側での使い方
Mapperクラスに追加したメソッドを呼び出すだけ。
FriendService.java
@Service
public class FriendService {
@Autowired
private UserFriendMapper userFriendMapper;
/**
* @return int insertした件数
*/
public int insertFriends(int userId, List<UserFriend> saveFriends) {
return userFriendMapper.insertBulk(saveFriends);
}
}