Mybatis不支持batchInsertOrUpdate返显id问题

 更新时间:2024年05月18日 10:00:52   作者:Victor _Lv  
这篇文章主要介绍了Mybatis不支持batchInsertOrUpdate返显id问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Mybatis不支持batchInsertOrUpdate返显id

需求背景

batchInsertOrUpdate 一批数据到 MySQL,并且需要将每条记录的 id 返显(write back)

现象

有ON DUPLICATE KEY UPDATE的 batchInsertOrUpdate 无法将所有 id write back,在我的例子中,是 batch 两条,但只有其中一条 id 能带回来,并且更严重的是映射到对应的对象偶尔也是错的。

mybatis-version: 3.5.5

<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO month (month, game_id)
        VALUES
        <foreach collection="list" item="f" separator=",">
            (#{f.month}, #{f.gameId})
        </foreach>
        ON DUPLICATE KEY UPDATE
        game_id = VALUES(game_id)
</insert>

把ON DUPLICATE KEY UPDATE删掉变成 batchInsert 则可以批量返显id

排查方法

Google + 追踪分析 Mybatis 源码 和 JDBC 源码 + Mybatis Github 和 Mybatis 官方 Google Groups 请教国外开发者。

心得

Mybatis 不支持 batchInsertOrUpdate 返显id,仅 batchInsert 可批量返显id,需拆分 batchInsert 和 batchUpdate;或者单条insertOrUpdate。

问题出在JDBC源码这StatementImpl.getGeneratedKeysInternal()。

Mybatis执行批量更新batch update方式

1、数据库连接必须配置:&allowMultiQueries=true

我的配置如下:

jdbc:mysql://10.20.13.16:3306/CALENDAR?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true

2、批量修改并加判断条件(修改字段可选)

    <!-- 批量更新赛程 -->
    <update id="updateMatchs" parameterType="java.util.List">
        <foreach collection="matchs" item="item" index="index" open="" close="" separator=";">
            update t_match
            <set>
                <if test="item.title !=null">
                    TITLE = #{item.title,jdbcType=VARCHAR},
                </if>
                <if test="item.homeScore !=null">
                    HOME_SCORE = #{item.homeScore,jdbcType=INTEGER},
                </if>
                <if test="item.visitScore !=null">
                    VISTT_SCORE = #{item.visitScore,jdbcType=INTEGER},
                </if>
                <if test="item.liveSource !=null">
                    LIVE_SOURCE = #{item.liveSource,jdbcType=VARCHAR},
                </if>
                <if test="item.liveURL !=null">
                    LIVE_URL = #{item.liveURL,jdbcType=VARCHAR},
                </if>
                <if test="item.isHotMatch !=null">
                    IS_HOT_MATCH = #{item.isHotMatch,jdbcType=VARCHAR}
                </if>
            </set>
        where HOME_TEAM_ID = #{item.homeTeamId,jdbcType=VARCHAR} and
        VISIT_TEAM_ID = #{item.visitTeamId,jdbcType=VARCHAR} and
        MATCH_TIME = #{item.matchTime,jdbcType=BIGINT}
        </foreach>
    </update>

java接口

    /**
     * 批量修改赛程
     *
     * @param matchs
     * @throws DaoException
     */
    void updateMatchs(@Param(value = "matchs")List<MatchBasic> matchs);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

最新评论