关于mybatis进行update更新时无法提交&update动态sql的使用

本文通过一个实际案例,强调了在数据库操作中,除了SELECT语句外,其他如INSERT、DELETE、UPDATE等操作都必须进行事务提交,否则数据不会被真正保存到数据库中。文章详细展示了一段动态SQL的代码示例,即使用MyBatis框架的动态SQL语法实现用户信息的更新,但若未正确执行事务提交,即使代码执行成功,数据库也不会反映任何更改。

首先,我发现代码明明执行成功,自己也并没有发现sql语句有问题,但是查看数据库却发现没有更新,最后才发现,没有进行事务的提交

数据的增删改查中,除了select语句,其余的语句都需要进行事务的提交。


动态sql(是我写的update语句)

<update id="updateInfo"  parameterType="com.zy.entity.User"> 

   UPDATE user 
       <trim prefix="set" suffixOverrides=",">  

       <if test="userName!=null">userName=#{userName},</if>  

       <if test="nickName!=null">nickName=#{nickName},</if>  

       <if test="avatar!=null">avatar=#{avatar},</if>  

       <if test="email!=null">email=#{email},</if>  

       <if test="age!=null">age=#{age},</if>  

       <if test="introduction!=null">introduction=#{introduction},</if>  
   </trim> 

   WHERE id=#{id}

</update>

 

<think> 根据用户的问题,用户遇到了在使用MyBatis-Plus执行update操作更新空值(null或空字符串)报错的问题。用户引用的资料中提到了MyBatis-Plus默认的更新策略会忽略null值,但用户需要更新空值(包括null和空字符串)到数据库。 从引用中我们可以总结出以下几点: 1. MyBatis-Plus默认的更新策略(FieldStrategy)是NOT_NULL,即只更新非null的字段。因此,当字段值为null,不会更新该字段。 2. 如果希望更新null值,可以通过设置字段的更新策略为IGNORED,这样无论字段值是否为null,都会更新。 3. 同样,对于空字符串,默认策略(NOT_EMPTY)也会忽略,所以也需要设置为IGNORED。 用户提到“更新空值报错”,可能的原因是在更新,数据库表字段有非空约束,而用户试图更新为null,导致数据库报错。但根据引用内容,更常见的问题是MyBatis-Plus不会更新null值(即不会将null值更新到数据库,而不是报错)。所以,用户的问题可能是: 情况1:用户希望更新为null,但MyBatis-Plus没有更新,导致数据库字段没有变成null(用户误以为报错)。 情况2:用户确实遇到了数据库约束导致的报错(例如,字段不允许为null,但用户试图更新为null)。 但用户的问题描述是“更新空值报错”,所以重点在“报错”上。因此,我们需要考虑两种情况: A. 由于MyBatis-Plus的更新策略导致没有更新空值,而用户期望更新空值,但数据库字段有非空约束,当用户更新为空值(null或空字符串),数据库报错(因为数据库约束不允许为空)。 B. 用户配置了更新策略为IGNORED,使得MyBatis-Plus会将null值更新到数据库,但数据库字段不允许为null,因此报错。 然而,根据引用内容,更可能的情况是:用户希望更新空值(包括null),但MyBatis-Plus默认不更新null值,所以用户需要改变更新策略。但是,如果数据库字段不允许为null,那么即使MyBatis-Plus更新了,也会触发数据库约束错误。 因此,解决步骤应该是: 1. 确认数据库表字段是否允许为null。如果字段不允许为null,那么更新为null就会报错,这应该检查业务逻辑,不应该更新为null。 2. 如果数据库字段允许为null,那么需要配置MyBatis-Plus的更新策略,使其可以更新null值和空字符串。 根据引用,配置更新策略的方法有两种: - 全局配置:在application.yml(或application.properties)中设置 - 局部配置:在实体类的字段上使用注解@TableField 具体做法如下: 全局配置(适用于所有字段): 在配置文件中(如application.yml)设置: ```yaml mybatis-plus: global-config: db-config: update-strategy: ignored # 低版本可能是 field-strategy ``` 注意:高版本(3.4.0+)中,属性名为`update-strategy`,低版本可能是`field-strategy`。另外,全局设置会作用于所有字段,可能会带来安全隐患(比如无意中将某些不允许为空的字段更新为null)。 局部配置(仅对特定字段): 在实体类的字段上添加注解: ```java @TableField(updateStrategy = FieldStrategy.IGNORED) private String name; ``` 这样,该字段就会忽略空值判断,即使为null或空字符串也会更新。 另外,如果用户需要更新空字符串,默认策略(NOT_EMPTY)也会忽略空字符串,所以同样需要设置IGNORED策略。 但是,用户提到“报错”,所以可能还需要考虑数据库约束问题。如果数据库字段有非空约束,那么即使MyBatis-Plus执行了更新(即生成了更新为null的SQL),数据库也会报错。因此,在更新为null之前,需要确保数据库字段允许为null。 总结解决方案: 1. 检查数据库表结构,确保要更新为null或空字符串的字段允许为空。 2. 配置MyBatis-Plus的更新策略为IGNORED(全局或局部),以便更新null和空字符串。 如果数据库字段不允许为null,那么不能更新为null,否则会报错。此应调整业务逻辑,避免更新为null,或者修改数据库表结构(如果允许)使其可为null。 注意:引用中提到的报错可能是由于数据库约束导致的,而不是MyBatis-Plus本身报错。因此,需要从两个方面入手:数据库约束和MyBatis-Plus更新策略。 最后,根据引用内容,用户可能混淆了“更新后数据库还是原来的值”(因为MyBatis-Plus忽略更新)和“报错”。但用户明确说了“报错”,所以我们优先考虑数据库约束导致的错误。 因此,回答应该包括: - 检查数据库表结构,确认字段是否允许为null。 - 配置MyBatis-Plus更新策略,使其可以更新null和空字符串(如果数据库允许)。 - 如果数据库不允许为null,则不能更新为null,需要调整业务逻辑或修改表结构。 同,提供配置示例。 </think>### MyBatis-Plus 更新空值报错的解决方案 在使用 MyBatis-Plus 执行 `update` 操作,若遇到空值(`null` 或空字符串)更新报错,核心原因是 **MyBatis-Plus 的字段更新策略(FieldStrategy)** 与数据库约束冲突。以下是详细解决方案: --- ### 一、问题根本原因 1. **MyBatis-Plus 默认更新策略** 默认采用 `FieldStrategy.NOT_NULL` 策略:若字段值为 `null`,则忽略该字段,不生成更新 SQL。 $$ \text{更新SQL} = \begin{cases} \text{包含字段} & \text{值} \neq \text{null} \\ \text{忽略字段} & \text{值} = \text{null} \end{cases} $$ 2. **报错场景** 当主动需要将字段更新为 `null` 或空字符串: - 若修改更新策略 → MyBatis-Plus 忽略该字段 → **数据库保留旧值**(非报错) - 若配置策略为 `IGNORED`,但数据库字段有 **非空约束** → 执行 SQL 报错(如 `Column 'xxx' cannot be null`) --- ### 二、解决方案(按优先级推荐) #### ✅ 方案1:修改字段更新策略(推荐) 在实体类字段上添加注解,强制更新空值: ```java public class User { @TableField(updateStrategy = FieldStrategy.IGNORED) // 忽略空值判断 private String name; } ``` - **效果**:无论字段值是否为 `null` 或空字符串,均会生成更新 SQL。 - **注意**:需确保数据库字段允许为 `null`,否则需同步修改表结构。 #### ✅ 方案2:全局配置更新策略 在 `application.yml` 中全局设置: ```yaml mybatis-plus: global-config: db-config: update-strategy: ignored # 全局忽略空值判断 ``` - **适用场景**:所有实体类字段均需支持空值更新。 - **风险**:可能意外覆盖不应为空的字段。 #### ✅ 方案3:自定义 SQL 语句 在 Mapper 接口中使用自定义 SQL: ```xml <!-- UserMapper.xml --> <update id="updateWithNull"> UPDATE user SET name = #{name}, age = #{age} <!-- 显式指定所有字段 --> WHERE id = #{id} </update> ``` ```java // Java 调用 userMapper.updateWithNull(user); // 手动控制更新逻辑 ``` - **优势**:完全绕过 MyBatis-Plus 的更新策略限制。 --- ### 三、避坑指南 1. **数据库约束检查** 执行空值更新前,确认目标字段是否允许为 `null`: ```sql SHOW CREATE TABLE user; -- 检查字段的 NULL 约束 ``` 若字段有 `NOT NULL` 约束,需先修改表结构: ```sql ALTER TABLE user MODIFY COLUMN name VARCHAR(255) NULL; ``` 2. **版本兼容性** - MyBatis-Plus ≥ 3.4.0:使用 `@TableField(updateStrategy)` - MyBatis-Plus < 3.4.0:使用 `@TableField(strategy = FieldStrategy.IGNORED)` 3. **批量更新策略** 使用 `updateBatchById()` ,需为 **每个字段** 单独配置 `updateStrategy`。 --- ### 总结流程 ```mermaid graph TD A[遇到空值更新报错] --> B{数据库字段是否允许为空?} B -->|是| C[配置字段策略为 IGNORED] B -->|否| D[修改数据库字段约束] D --> C C --> E[重新执行更新操作] ``` 通过调整更新策略或数据库约束,即可解决空值更新报错问题。优先推荐**方案1**,安全性更高[^1][^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值