【笔记】mybatis 遇到所有更新的字段都是null或空字符串

本文通过一个实际案例探讨了在使用MyBatis进行数据库更新操作时遇到的问题。当作为查询条件的字段未被包含在更新语句中时,可能会导致SQL语句拼接错误。为了避免这类问题,建议在更新语句中始终包含一个唯一标识字段。

在做mybatis更新时,因为我想到作为查询的字段不需要更新所以就没写在trim里面,结果出现了如下错误:


这里的altBefore 和 altAfter两个字段都是空字符串,所以mybatis在拼接语句时报了上面的错误,并没有把这两个字段拼上,所有在写更新语句时最好加上一个唯一标识的字段,以避免出现上面的错误


<think> 我们正在讨论MyBatis中如何查询字段NULL字符串的数据。根据用户的上一次问题,我们需要结合之前的引用内容来给出解决方案。 引用[1]和[4]提到了通过类型处理器(typeHandler)将查询结果中null字段转换为字符串,但这不是查询条件,而是结果处理。 引用[2]提到了在查询条件中,如果字段是数字类型(比如Integer),那么传入0会被判断为字符串的问题,建议只使用`!= null`而不使用`!=''`。 引用[3]则展示了在MyBatis-plus中使用条件构造器查询字段null字符串的方法。 但是,用户当前的问题是如何在MyBatis中查询字段NULL字符串的数据(作为查询条件)。所以,我们需要构建一个查询条件,使得该字段NULL字符串('')的数据都被查询出来。 在SQL中,我们可以这样写: WHERE column_name IS NULL OR column_name = '' 在MyBatis的XML映射文件中,我们需要动态构建这个条件。注意:如果该字段是数类型,那么就不存在字符串('')的情况,所以这种情况只适用于字符串类型的字段。 具体实现步骤如下: 1. 确定查询字段的类型:必须是字符串类型(如VARCHAR),因为数类型不会有字符串('')的情况(数字段如果为,则NULL;如果允许字符串,那么数据库设计可能不合理,因为数字段存储字符串通常没有意义)。 2. 在MyBatis的XML中,可以直接使用如下条件: <where> ...其他条件... AND (column_name IS NULL OR column_name = '') </where> 3. 但是,如果这个条件需要动态添加(比如根据传入参数决定是否查询),那么可以使用<if>标签。 4. 如果同时需要查询其他条件,并且这个条件是可选的,我们可以这样写: 示例代码(假设我们有一个String类型的参数`includeNullAndEmpty`,当这个参数存在且为某个时,我们就添加这个条件): 但是,通常我们不会专门传一个参数来控制,而是直接作为查询条件的一部分。如果我们想要查询某个字段NULL字符串,那么可以直接在查询条件中写出。 另一种情况:我们可能有一个对象作为参数,该对象有一个字段(例如`name`),我们想查询`name`字段NULL字符串的记录,同时可以传入其他条件。 例如,我们有一个查询对象QueryObject,其中包含一个字段`filterNullAndEmpty`,当该字段为true时,我们就对某个特定字段(如`fieldName`)添加条件。 XML映射文件示例: ```xml <select id="selectWithNullAndEmpty" resultType="YourEntity"> SELECT * FROM your_table <where> <!-- 其他条件 --> <if test="query.otherField != null"> AND other_field = #{query.otherField} </if> <!-- 当需要过滤特定字段NULL字符串时 --> <if test="query.filterNullAndEmpty == true"> AND (field_name IS NULL OR field_name = '') </if> </where> </select> ``` 5. 如果我们想要查询的字段是动态指定的,那么可能需要使用动态SQL的foreach?不太适用。通常,我们只能写死字段名。 6. 如果使用的是MyBatis-Plus,那么可以使用条件构造器,如引用[3]所示: ```java LambdaQueryWrapper<Entity> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.isNull(Entity::getFieldName) // 字段NULL .or() .eq(Entity::getFieldName, ""); // 者为字符串 List<Entity> list = mapper.selectList(queryWrapper); ``` 7. 注意:在数据库中,字符串('')和NULL是不同的。字符串是明确的长度为0的字符串,而NULL表示未知未定义。 8. 如果字段字符串类型,并且我们想同时查询NULL字符串,那么使用`IS NULL`和`=''`即可。 9. 如果字段是其他类型(如整数),那么就不存在字符串的情况,只需查询NULL即可。 10. 另外,在引用[2]中提到,对于数类型的字段,在动态条件中不要同时判断`!= null and != ''`,因为数类型如果传入0,可能会被误判(因为0!=null成立,但0!=''这个条件在MyBatis的OGNL表达式中,0会被当成数字,而和字符串比较时,OGNL会将字符串转为0?但实际测试发现,在MyBatis中,如果字段是Integer类型,那么传入0时,`test="field != null and field != ''"`中的`field != ''`会返回false,因为0不等于字符串(在OGNL中,字符串和0比较是false,因为类型不同)。所以,对于数类型,只需要判断`!= null`即可。 因此,对于用户的问题,我们分两种情况: - 字符串类型:使用 `IS NULL OR = ''` - 数类型:使用 `IS NULL` 当然,如果数据库设计允许数类型字段字符串(虽然不合理),那么需要将其作为字符串类型查询,但这种情况很少见。 总结回答: 在MyBatis中查询字段NULL字符串的数据,需要根据字段类型分别处理: - 对于字符串类型字段(如VARCHAR),在SQL条件中使用:`(column_name IS NULL OR column_name = '')` - 对于数类型字段,只需要查询NULL:`column_name IS NULL` 在MyBatis的XML映射文件中,可以这样写(假设我们有一个字符串字段`strField`和一个数字段`intField`): ```xml <select id="selectByCondition" resultType="YourEntity"> SELECT * FROM your_table <where> <!-- 查询字符串字段NULL字符串 --> <if test="query.filterStrField == true"> AND (str_field IS NULL OR str_field = '') </if> <!-- 查询数字段NULL --> <if test="query.filterIntField == true"> AND int_field IS NULL </if> </where> </select> ``` 者,如果我们希望无论什么情况,只要某个字段需要这个条件就加上,那么可以写死: ```xml <select id="selectWithNullAndEmptyStr" resultType="YourEntity"> SELECT * FROM your_table WHERE (str_field IS NULL OR str_field = '') </select> ``` 如果使用MyBatis-Plus,则可以使用条件构造器,更加简便。 最后,生成相关问题: </think> ### MyBatis查询字段NULL字符串的数据方法 在MyBatis中查询字段为**NULL字符串('')** 的数据,需要通过SQL条件结合动态SQL实现。关键是根据字段数据类型采用不同策略: --- ### 一、字符串类型字段(VARCHAR等) #### 1. **基础SQL条件** ```sql WHERE (column_name IS NULL OR column_name = '') ``` #### 2. **MyBatis XML实现** ```xml <select id="selectNullOrEmptyString" resultType="YourEntity"> SELECT * FROM your_table <where> <!-- 动态条件示例 --> <if test="otherParam != null"> AND other_column = #{otherParam} </if> <!-- 查询字段NULL字符串 --> AND (target_column IS NULL OR target_column = '') </where> </select> ``` #### 3. **MyBatis-Plus实现(Lambda表达式)** ```java LambdaQueryWrapper<Entity> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.isNull(Entity::getTargetColumn) // NULL检查 .or() .eq(Entity::getTargetColumn, ""); // 字符串检查 List<Entity> result = mapper.selectList(queryWrapper); ``` --- ### 二、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值