Mybatis中如何确定需要更新的字段?(不要答通过Null或为空判断)

owen1759 2015-07-03 10:55:09
更新一条记录一般都是传入一个Entity实例,然后Sql语句通过主键查找要更新的记录、通过字段为Null或为空判断要更新的字段。
但是,这种做法存在Bug:
比如某人在某个允许为空的字段(例如[家庭住址])填写了内容,然后他想删除掉,于是他在页面上把这个字段的内容清空, 然后点保存,然后…他会发现原先的内容居然还在,没有办法清除了!

或许这个实例,大家会说,那我就只判断Null不判断空好了。

可是,假如这个允许为空的字段是一个日期型呢?我们如何判断是要清空这个字段还是保持不变?

或许大家会说,你在前面的业务层肯定能知道是要清空还是要保持不变,但是问题在于,Mapper层要怎么判断呢?判断Null和判断空都不可行了,那么应该怎样判断呢?
...全文
32829 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
snail131 2019-02-14
  • 打赏
  • 举报
回复
我遇到过和楼主一样的问题,我的解决方法是
1、java中DO层实体类,非必填字段设置@TableField (strategy = FieldStrategy.IGNORED)

2、更新操作,和前端对接的逻辑是,非必填字段传null或"",则表示用户想要擦掉这个字段的值。这样更新操作就能
正常擦除非必填字段的值

3、而当其他的业务逻辑也需要更新表,并且只需要更新一个字段的时候,则需要先通过id查询详情,用更新字段替换
再执行update
Study219222 2018-12-27
  • 打赏
  • 举报
回复
<!-- 动态更新-->
<update id="updateBook" parameterType="map">
update book

<trim prefix="set" suffixOverrides=",">
<if test="_parameter.containsKey('bookName')">
book_name=#{bookName},
</if>
<if test="_parameter.containsKey('bookPrice')">
book_price=#{bookPrice},
</if>
<if test="_parameter.containsKey('bookPage')">
book_page=#{bookPage}
</if>
</trim>
where id=#{id}
</update>

参考地址
引用
https://blog.csdn.net/xl_1803/article/details/83472576
Study219222 2018-12-27
  • 打赏
  • 举报
回复
请参考 https://blog.csdn.net/xl_1803/article/details/83472576
  • 打赏
  • 举报
回复
我也遇到了 最后用笨方法解决的 <if test="departmentId != null and departmentId != 0" > departmentId = #{departmentId,jdbcType=INTEGER}, </if> <if test="departmentId == 0" > departmentId = null, </if>
Tlimited 2017-09-09
  • 打赏
  • 举报
回复
通过ognl来判断 <if test="@Ognl@isNotEmpty(customerName)"> AND crm.customer_name LIKE '%${customerName}%' </if> <if test="@Ognl@isNotEmpty(financePayBank)"> AND finance_pay_bank LIKE '%${financePayBank}%' </if>
艺设院长 2017-01-09
  • 打赏
  • 举报
回复
引用 30 楼 weiwei566716 的回复:
你好 , 你这个问题解决了吗 ? 我也是同样的需求,
可以写两个sql啊,mybatis生成的xml文件update就是两个啊,一个是updateByPrimaryKey更新全部字段,一个是updateByPrimaryKeySelective更新非空字段
weiwei566716 2016-10-27
  • 打赏
  • 举报
回复
你好 , 你这个问题解决了吗 ? 我也是同样的需求,
山顶的男人 2016-09-25
  • 打赏
  • 举报
回复
引用 18 楼 u010513629 的回复:
我的想法没那么复杂,和判断为null的做法类似,你设置一个初始值,判断如果是那个初始值就不更新,如果不是就更新. <if test="studentName !='a' "> STUDENT_NAME =#{studentName,jdbcType=VARCHARA} </if>
此写法有误,应该<if test="studentName !='a' .toString()"> or <if test='studentName !="a" '>
qq_29503819 2016-08-26
  • 打赏
  • 举报
回复
这样行吗?每次表单提交的时候都对数据库进行全量更新,不再判断某字段是否为空.
xmdxzyf3 2016-08-18
  • 打赏
  • 举报
回复
entity中的基本类型全部定义为包装类型,sql中只要判断不是为null就更新,这样即使前端设置某个字符串为空依然可以更新。
lovgge 2016-02-24
  • 打赏
  • 举报
回复
24楼的方法好,设置初始值
hersing 2015-12-29
  • 打赏
  • 举报
回复
11楼说的这么清楚了。。
鸣鸣Amadues 2015-12-28
  • 打赏
  • 举报
回复
另外,一般对于有实际业务含义的字段,都有规定初始值的。 字符串型初始值是空字符串,注意是空字符串,不是null 整型变量初始值是0 日期型是0000-00-00 时间型是00:00:00
鸣鸣Amadues 2015-12-28
  • 打赏
  • 举报
回复
做更新一般两种方法,一种是根据对象实体整体更新,这种更新是每次覆盖的,所以要先把对象记录先读出来,改完后再全部字段更新回去。 另外一种是更新指定字段,这种就是拼SQL。 大部分时候都建议使用根据对象来更新的方法,虽然这种方法哪怕只更新一个字段也要每次覆盖全部字段,但是写代码简单。
feiepuhuo001 2015-12-28
  • 打赏
  • 举报
回复
我觉得吧,持久层就不应该考虑这个字段要不要更新或者说这个字段该怎么更新,都考虑完了还要逻辑层干嘛?持久层就是一个单纯的与数据库交互的层面,只要考虑怎么与数据库交互,sql语句是不是最优的,有没有可能报错等问题。至于楼主说的,比如地址这个字段如果为空该怎么更新这个问题,可以在逻辑层做出一个判断,如果没有值就给这个字段设为空,持久层必然是要做非空验证的,为空就不更新,这样不就解决了吗?而且,我觉得如果一个用户在页面把地址这个字段给删了,必然是不想保存了,那就直接更新完事,如果业务上不允许删,那就只给客户看,不给操作就可以了
心随自在飞 2015-12-28
  • 打赏
  • 举报
回复
那你就多写几条SQL呀, 不同情况调不同的方法就行了呀 SQL说的都不算了,那持久化还有什么用
lcigo 2015-12-28
  • 打赏
  • 举报
回复
new一个新的entity,把id和需要update的字段复制过去。
JMxg 2015-07-09
  • 打赏
  • 举报
回复
我的想法没那么复杂,和判断为null的做法类似,你设置一个初始值,判断如果是那个初始值就不更新,如果不是就更新. <if test="studentName !='a' "> STUDENT_NAME =#{studentName,jdbcType=VARCHARA} </if>
lan125709702 2015-07-09
  • 打赏
  • 举报
回复
引用 14 楼 owen1759 的回复:
[quote=引用 12 楼 lan125709702 的回复:] 我一般的做法是COLUMN1 = NVL(#传进来的字段#,COLUMN1)
这不一样会导致Bug么?假如有人要把它的生日更新为Null,提交之后发现根本没更新。[/quote]v 那这个问题不是DAO能解决的,放在业务层去解决吧
风过无痕1110 2015-07-08
  • 打赏
  • 举报
回复
1.这个问题不能在持久层dao中得到解决,首先,dao不应该考虑前端业务的问题 2.那么这个问题就需要业务层来解决,然后你这里其实有个问题,就是不规范,就是完全不清楚前端是 想更新这个空字段呢,还是不想更新,就是如果你业务层提供一个通用的方法,但是由于没有足够清楚的 规范,导致没法判断,所以前端到业务层,需要一个规范,比如你要将这个字段制空,就需要传特殊字符如-1,然后 业务层就可以做成一个通用的东西了,说白了,就是一定要清楚明白前端要做什么,因为你这里,null和空已经不能 判断前端是要更新呢,还是压根不更新这个字段
加载更多回复(15)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧