loading

Mybatis - Map 集合与 update 语句动态更新字段

业务需求

如果一张表的字段非常多,一次性更新的字段也非常多,写 Mybatis XML 是非常痛苦的事情。我们可以取消实体类,通过 Map 代替实体类接收前端传递过来的 JSON 数据。

但是,会遇到一个问题,数据库的字段命名和 JS、JSON 等命名不一样,一个是下划线,一个是驼峰命名法。

所以,需要把 Map 里面的每一个 Key 转换为下划线命名的 Key,方便在 Mybatis 进行 foreach 插入。

理想状态下的 update 语句:

file:[OrderMapper.xml]
<update id="update">
    UPDATE orders
    <trim prefix="SET" suffixOverrides=",">
        <foreach collection="map" item="value" index="key">
            ${key} = #{value},
        </foreach>
    </trim>
    WHERE id = #{id};
</update>

工具类

把 Map 中以驼峰命名的 Key 转换为下划线命名的工具类:

file:[utils/ToUnderscore.java]
public record ToUnderscore(Map<String, Object> map) {

    record NewMapKey(String oldKey, String newKey, Object value) {
    }

    private void replace(ArrayList<NewMapKey> list) {
        for (NewMapKey item : list) {
            map.remove(item.oldKey());
            map.put(item.newKey(), item.value());
        }
    }

    public void convert() {
        String regEx = "[A-Z]";
        Pattern pattern = Pattern.compile(regEx);
        ArrayList<NewMapKey> list = new ArrayList<>();

        for (String oldKey : map.keySet()) {
            Matcher matcher = pattern.matcher(oldKey);
            while (matcher.find()) {
                StringBuilder sb = new StringBuilder(oldKey);
                String newKey = "_" + matcher.group().toLowerCase();
                sb.replace(matcher.start(), matcher.start() + 1, newKey);
                list.add(new NewMapKey(oldKey, sb.toString(), map.get(oldKey)));
            }
        }

        replace(list);
    }

}

使用方式

file:[OrderService.java]
@Transactional
public R<Object> update(Map<String, Object> map, Integer id) {
    // 1. 删除 Map 中存储的不需要的字段
    map.remove("items");
    map.remove("id");
    // 2. 开始转换字段命名
    ToUnderscore tu = new ToUnderscore(map);
    tu.convert();
    int flag = mapper.update(tu.map(), id);
    if (flag != 0) return R.build(HttpCodes.OK, "更新数据成功");
    else return R.build(HttpCodes.NO, "操作失败");
}
posted @ 2023-06-19 02:44  Himmelbleu  阅读(30)  评论(0编辑  收藏  举报