update 常用属性
update 有几个常用的属性, 但是通常只需要设置 id 即可.
- id: sql 片段在命名空间内的唯一标识, 和 mapper 中方法名保持一致
- parameterType: 参数类型, 通常都可以省略.
- flushCache: 是否刷新 (清空) 一级缓存和二级缓存, 默认为 true. 笔者尝试设置为 false, 并不生效. 所以使用默认即可.
- timeout: sql 执行超时时间, 默认未设置, 由数据库驱动决定.
- statementType: 执行 sql 时使用的 statement 类型, 默认为 PREPARED. 可选值为: STATEMENT, PREPARED 或 CALLABLE 的一个
<update id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
</update>
update 的返回值
JDBC 执行更新语句时, 返回的是 SQL 执行影响的记录条数. MyBatis 可将此返回结果自动封装为 int, long, boolean 以及其对应的包装类型.
我擦, 还可以封装为 boolean 类型的?
常用 SQL 片段
<!-- 通过 id 删除 -->
<update id="update">
update t_employee
set id = #{id}, name = #{name}, sex=#{sex}, entryDate =#{entryDate}
where id = #{id}
</update>
<!-- 更新不为空的属性 -->
<update id="updateNotNull">
update t_employee
<set >
<if test="name != null"> name = #{name}, </if>
<if test="sex != null"> sex = #{sex}, </if>
<if test="entryDate != null"> entryDate = #{entryDate}, </if>
</set>
where id = #{id}
</update>
动态更新
<update id="updateOne" parameterType="com.inspur.search.data.EntityRelation">
UPDATE ENTITY_RELATION
<trim prefix="set" suffixOverrides=",">
<if test="srcId!=null">SRC_ID=#{srcId},</if>
<if test="srcType!=null">SRC_TYPE=#{srcType},</if>
<if test="destId!=null">DEST_ID=#{destId},</if>
<if test="destType!=null">DEST_TYPE=#{destType},</if>
<if test="relType!=null">REL_TYPE=#{relType},</if>
<if test="status!=null">STATUS=#{status},</if>
<if test="snId!=null">SN_ID=#{snId},</if>
</trim>
WHERE id=#{id}
</update>
中午睡觉的时候, 来了一个噩耗, 说线上亏钱了, 有一万多块钱. 我写的 bug, 真是, 捶死病中惊坐起.
记录下 bug 原因:
起因是因为一个重置功能, 会给商家上分额度, 重置为初始额度.
带哪里用的是如下代码:
shop.setAddPoints(shop.getInitPoints());
shopMapper.update(shop);
就是这个更新代码, 坑啊....
好吧, 说说原因,initPoints 字段在数据库里面是 null, 也就是需要把 addPoints 更新为 null, 看到这里大家估计就知道是怎么一回事了吧, 哎! 回去我看看 update 里面到底是怎么写的, 是不是有 if 判断.
避免方法, 数据库字段需要设置不为空, 并且默认为 0.
从 csv 取 出来的数据忘记去掉空格了, 太坑了 , 这里记载下
https://www.163.com/dy/article/EVHOU6T705319WXB.html
解决 mybatis 无法更新空字符串或者 null 问题
有一种方法, 但是不推荐: 在配置文件里加全局配置, 使 mybatis 不忽略所有 null 和空字符串. 这样做的缺陷是, 不更改的数据也会被置空.
有效方法: 单独在有置空需求的 entity 实体类中加对应字段的注解@TableField.
注解中:
value 值为对应字段.
updateStrategy = FieldStrategy.IGNORE 将此字段的空值判断忽略 (IGNORE)
注解之后还不够. 因为会报 error 无效的列类型:1111
此时是因为传进来的空值不确定类型. 只需要在注解中加入 jdbcType 即可.
例:
链接:https://www.jianshu.com/p/5a0524ea2675
- update 元素的 parameterType 属性可以不用写,Mybatis 可以自动推断出传入的参数类型.
#{name}
,#{salary}
,#{id}
这些 OGNL 表达式中的名称要跟 User 对象的属性名称一致, 不然会报错说反射异常, 在 User 类中找不到对应的 getter 方法.
mybatis plus 字段为 null 更新
当 Mybatis plus 执行 update 的时候, 默认是不会更新 null 的字段, 只更新有数据的字段. 这适用于大部分的业务, 但有时候确实想用 null 去更新, 那就需要添加@TableField(updateStrategy = FieldStrategy.IGNORED) 注解.
链接:https://juejin.cn/post/6844904069119606798
另外一个例子
首先我写的 sql 语句:
<update id="updateProject" parameterMap="project">
UPDATE project SET name =#{name},remote_log_url=#{remoteLogUrl},map_data=#{mapData}
WHERE id=#{id}
</update>
这种情况下, 如果某个字段为空或者空字符串, 就会报错, 后面我进行了过滤处理:
<update id="updateProject" parameterMap="project">
UPDATE project
<trim prefix="set" suffixOverrides=",">
<if test="name!=null and name!=''">name=#{name},</if>
<if test="remoteLogUrl!=null and remoteLogUrl!=''">remote_log_url=#{remoteLogUrl},</if>
<if test="mapData!=null and mapData!=''">map_data=#{mapData},</if>
</trim>
where id=#{id}
</update>
这种方式的好处就是, 如果某个字段没有更新或为空字符串, 就自动过滤掉该字段. 这种的好处就是防止, 只更新修改过值的字段.
原文链接:https://blog.csdn.net/zy345293721/article/details/103821026
文章评论