!=null and !='' 并不能防Integer 0

本文探讨了MyBatis中OGNL表达式处理数字为0时的特殊行为,解释了为何在条件判断中数值0会被视为false,并提供了解决方案。
<if test="state != null and state != ''">state = #{state}</if>

转载:https://blog.youkuaiyun.com/every__day/article/details/78964180

  本来想自己写的  ,结果看到别人写的比我写的详细一些,我就转载了.

当状态值设置为0时,操作完了,数据库没反应,没有设置为0 
仔细检查了代码,代码没有出错。回避问题的解决办法,把状态用1和2表示,不使用0,一切正常,问题消失了。 
出来混的,迟早要还的,后来又遇到这个问题:

<if test="totalNum!= null and totalNum!= ''">total_num = #{totalNum}</if>

当totalNum 传入值为0时,操作结束后,数据库显示为该值不是0,代码没问题,传值也没问题,就是没达到预期的效果,我知道是mybatis里面的问题。世界是最遥远的距离,就是我新手造的bug,它就在那里,可我就是找不出来。经过一番摸索,知道了问题所在: 
MyBatis的表达式是用OGNL处理的。OGNL表达式的规则如下

Interpreting Objects as Booleans
Any object can be used where a boolean is required. OGNL interprets objects as booleans like this:

If the object is a Boolean, its value is extracted and returned;

If the object is a Number, its double-precision floating-point value is compared with zero; non-zero is treated as true, zero as false;

If the object is a Character, its boolean value is true if and only if its char value is non-zero;

Otherwise, its boolean value is true if and only if it is non-null.

根据这一条“If the object is a Number, its double-precision floating-point value is compared with zero; non-zero is treated as true, zero as false;”   
totalNum!= ” 传入0时,表达式的值为false;所以这名不执行。 
解决办法,把这个删掉就可以了。

<if test="totalNum!= null">total_num = #{totalNum}</if>
  • 1

本来只有String类型的才会进行这样的判断——totalNum!= ”,其实是自己码代码时只顾自制粘贴,自己给自己埋了个坑。

这里有必要再提一个“坑”,如果类似于String str =”A”; 这样的写法时时,根据第三条规则,OGNL将会识别为Java 中的 char类型,显然String 类型与char类型做==运算会返回false,从而导致表达式不成立。解决方法很简单,修改为

<if test='str!= null and str == "A"'>

我的方法 :<if test='str!= null'>  我的方法是删掉 !='' 

 

 

 

<think>我们正在处理一个由JsqlParser抛出的ParseException,具体错误信息是遇到了意外的令牌"pass_type"。根据引用[1][2][3]中的案例,这类错误通常与SQL语法问题或解析器兼容性有关。结合用户提供的MyBatis SQL查询语句片段,我们需要分析SQL中"pass_type"出现的位置及其上下文。 ### 问题分析 1. **SQL语法错误**:检查`pass_type`是否被正确使用(例如:是否为保留字、是否缺少引号等)。 2. **别名冲突**:引用[1]提到别名"query"引发异常,类似地"pass_type"作为别名可能冲突。 3. **逗号使用不当**:引用[3]表明多余的逗号会导致解析失败,需检查"pass_type"前后是否有非法逗号。 4. **解析器版本问题**:旧版jsqlparser可能无法解析某些语法。 ### 解决方案 #### 1. 检查修正SQL语法 假设原SQL片段如下(用户未提供完整SQL,此处为推测): ```sql SELECT id, pass_type, name FROM table_name ``` 若数据库将`pass_type`视为保留字(如MySQL中的`PASSWORD`),需用反引号包裹: ```sql SELECT id, `pass_type`, name FROM table_name -- MySQL -- 或 SELECT id, [pass_type], name FROM table_name -- SQL Server ``` #### 2. 处理别名冲突 若`pass_type`作为别名(如`COUNT(*) AS pass_type`),更换为无冲突别名: ```sql -- 原语句(可能引发异常) SELECT COUNT(*) AS pass_type FROM table_name -- 修改后 SELECT COUNT(*) AS passType FROM table_name -- 改用驼峰命名 ``` #### 3. 排查逗号错误 引用[3]的案例由多余逗号导致异常。检查`pass_type`所在行是否存在非法逗号,例如: ```sql -- 错误示例(末尾多逗号) SELECT id, pass_type, FROM table_name -- 修正后 SELECT id, pass_type FROM table_name ``` #### 4. 升级jsqlparser版本 在`pom.xml`中更新至最新稳定版(如4.6): ```xml <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>4.6</version> </dependency> ``` #### 5. MyBatis-Plus特定配置 若使用MyBatis-Plus分页插件,确保正确配置`DbType`(引用[1][3]): ```java @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 按实际数据库类型配置 return interceptor; } ``` ### 调试建议 打印MyBatis最终执行的SQL语句,直接在数据库客户端运行以验证语法正确性。例如,在`application.yml`中开启SQL日志: ```yaml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` ### 总结步骤 1. 检查SQL中`pass_type`是否需转义(添加反引号/方括号)。 2. 避免使用可能冲突的别名。 3. 检查删除非法逗号。 4. 升级jsqlparser依赖。 5. 确认MyBatis-Plus分页插件配置正确。 > **注意**:若问题仍存在,请提供完整SQL语句以便进一步分析[^1][^2][^3]。 --- §§相关问题§§ 1. MyBatis中如何正确转义SQL保留字? 2. 如何升级jsqlparser依赖解决版本冲突? 3. MyBatis-Plus分页插件的常见配置错误有哪些? </think>### 解决JsqlParser解析SQL时出现`ParseException: Encountered unexpected token: "pass_type"`的方法 #### 问题根本原因分析 根据错误信息和引用案例([1][2][3]),该异常通常由以下原因引起: 1. **SQL语法不规范**:`pass_type`可能是字段名或别名,未正确处理特殊字符或保留字 2. **别名冲突**:`pass_type`作为别名时与SQL保留字冲突(类似引用[1]的"query"问题) 3. **逗号使用错误**:查询语句中存在多余的逗号(类似引用[3]的逗号错误) 4. **解析器版本问题**:jsqlparser版本过旧或不兼容 --- #### 解决方案(逐步操作) ##### 1. 检查修正SQL语法(首要步骤) 在MyBatis的`<select>`语句中: ```xml <select id="selectSize" resultType="java.lang.Integer"> SELECT COUNT(*), pass_type -- 此处可能是问题源头 FROM user_table WHERE status = 1 </select> ``` **修正方案**: ```xml <select id="selectSize" resultType="java.lang.Integer"> SELECT COUNT(*) AS total_count, `pass_type` AS passType -- 添加反引号和别名 FROM user_table WHERE status = 1 </select> ``` - 使用反引号包裹特殊字段名 `` `pass_type` `` - 添加无冲突的别名 `passType`(避免使用下划线) ##### 2. 处理逗号语法错误(引用[3]的解决方案) 检查`pass_type`前后的逗号使用: ```sql -- 错误示例(结尾多余逗号) SELECT id, name, pass_type, FROM table -- 正确写法 SELECT id, name, pass_type FROM table ``` ##### 3. 配置MyBatis-Plus分页插件(关键) 在Spring配置类中添加(根据实际数据库类型选择): ```java @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // MySQL示例 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 或SQL Server // interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.SQL_SERVER)); return interceptor; } ``` ##### 4. 升级jsqlparser版本(解决兼容性) 在`pom.xml`中强制指定最新版本: ```xml <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>4.6</version> <!-- 2023年稳定版 --> </dependency> ``` ##### 5. 关闭SQL优化(临时方案) ```java PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(); pageInterceptor.setOptimizeJoin(false); // 关闭优化 interceptor.addInnerInterceptor(pageInterceptor); ``` --- #### 调试建议 1. **打印实际SQL**:在日志中输出最终执行的SQL语句 2. **数据库验证**:复制SQL到数据库客户端直接执行 3. **简化查询**:逐步删除字段定位问题字段 > **经验提示**:字段名包含下划线`_`时,在jsqlparser中容易触发解析异常,建议使用驼峰命名[^1][^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值