Java基本类型与包装类在MyBatis中的应用指南
基本类型及其它的包装类在写接口时要注意什么
在Java开发中,我们经常使用基本数据类型和它们的包装类。这两者之间有着重要的区别,尤其是在MyBatis等ORM框架中进行动态SQL判断时,正确理解这些差异至关重要。本文将深入探讨基本类型与包装类的区别,并分析在MyBatis中如何正确进行非空判断。
一、基本类型与包装类
Java提供了8种基本数据类型,以及对应的包装类:
基本类型->默认值 | 包装类对象 | 默认值 | 大小/范围 |
---|---|---|---|
byte-> 0 | Byte | null | 8位,-128~127 |
short> 0 | Short | null | 16位,-32768~32767 |
int> 0 | Integer | null | 32位,-2^31~2^31-1 |
long> 0L | Long | null | 64位,-2^63~2^63-1 |
float> 0.0f | Float | null | 32位,IEEE754标准 |
double> 0.0d | Double | null | 64位,IEEE754标准 |
char> '\u0000' | Character | null | 16位,Unicode字符 |
boolean> false | Boolean | null | true/false |
关键区别:
存储方式:基本类型是值类型,直接存储数据值;包装类是引用类型,存储对象的引用。
默认值:基本类型有默认值(如int为0),而包装类默认值为null。
空值:包装类可以为null,表示缺失或未设置的值,而基本类型不能为null。
二、MyBatis中的非空判断
在MyBatis的动态SQL中,我们经常使用<if>
标签进行条件判断。由于基本类型和包装类的特性不同,判断方式也需要特别注意。
1. 数值类型(Integer、Long等)
对于数值类型的包装类(如Integer、Long),只需判断是否为null,不需要判断空字符串。
正确示例:
<if test="status != null">AND status = #{status}
</if>
错误示例:
<if test="status != null and status != ''">AND status = #{status} </if>
解释:数值类型包装类只需判断null,因为空字符串('')对于数值类型是没有意义的。如果使用基本类型(如int),则不需要判断null,因为它总是有值(默认0),但这可能影响业务逻辑(无法区分未设置值和0)。
2. 字符串类型(String)
字符串是引用类型,需要同时判断null和空字符串。
正确示例:
<if test="username != null and username != ''">AND username = #{username}
</if>
解释:字符串需要判断null和空字符串,因为这两种情况都表示没有有效的值。
3. 布尔类型(Boolean)
布尔包装类型只需判断是否为null。
正确示例:
<if test="active != null">AND is_active = #{active}
</if>
解释:Boolean包装类型需要判断null,以区分未设置值、true和false。如果使用基本类型boolean,则不需要判断null,但它只能表示true或false,无法表示未设置。
4. 浮点类型(Float、Double)
浮点类型的包装类只需判断是否为null。
正确示例:
<if test="price != null">AND price = #{price}
</if>
解释:与整数类型类似,浮点类型包装类只需判断null,不需要判断空字符串。
三、底层原理分析
MyBatis使用OGNL(Object-Graph Navigation Language)表达式进行条件判断。OGNL在处理基本类型和包装类时,会自动进行类型转换,但我们需要明确区分null和默认值。
包装类:可以为null,表示该字段未被赋值。
基本类型:不能为null,总是有默认值(如0、false等)。
在实体类中使用包装类的优势在于可以区分"未赋值"和"默认值"。例如,对于Integer类型的status字段,null表示未设置,0表示设置值为0。而基本类型int的status字段,0可能是默认值,也可能是业务设置的0,无法区分。
四、常见错误与最佳实践
常见错误:
对数值类型判断空字符串:
<!-- 错误示例 --> <if test="userId != null and userId != ''">user_id = #{userId} </if>
忽略基本类型的默认值:使用基本类型时,默认值可能影响业务逻辑,比如默认0可能被当作有效值。
最佳实践:
在实体类中使用包装类型:这样可以更好地区分"未赋值"和"默认值"场景。
数值类型只需判断null:不需要判断空字符串。
字符串类型判断null和空字符串:确保两种情况下都不会生效。
布尔类型判断null:区分未设置值和设置值。
五、总结
在MyBatis动态SQL中,正确处理基本类型和包装类的非空判断是编写健壮代码的关键。总结如下:
使用包装类型可以更好地区分未设置值和默认值。
对于数值类型(Integer、Long等),只需判断
!= null
,不需要判断空字符串。对于字符串类型,需要同时判断
!= null and != ''
。对于布尔类型,只需判断
!= null
。避免对数值类型进行空字符串判断,这是常见的错误用法。
遵循这些原则,可以编写出更加清晰、健壮和可维护的MyBatis动态SQL语句。