需求背景
作为一名Java CRUD Coder,日常开发中会遇到类似的需求:通过下拉列表选择“是”或“否”来对数据库中的数据进行筛选。如果此时前端的传参是boolean
类型的true
和false
,后端Mapper层的代码可能会遇到需要构造类似if (param.existFlag) and table.id not in (xxxx1,xxxx2)这样的条件查询,如果你们的ORM框架使用的是MyBatis/MyBatis Plus,请看下文内容。
MyBatis参数映射
错误写法
Java中在写判断条件时,可以使用:
代码语言:javascript复制if(existFlag) {
//do something
}
在MyBatis的XML中,不可以使用类似的写法:
代码语言:javascript复制<if test="param.existFlag">
AND id = 1
</if>
正确写法
代码语言:javascript复制<if test="param.existFlag != null and param.existFlag == true">
AND id = 1
</if>
注意事项及优化
缺陷
当我们需要在SQL中需要根据true、false、null执行不同的逻辑时,尽管MyBatis支持上述写法,但这种写法难免不太容易理解。
代码语言:javascript复制<select id="selectUsersByFlag" resultType="User">
SELECT * FROM users
<where>
<if test="existFlag != null and existFlag == true">
AND id = 1
</if>
<if test="existFlag != null and existFlag == false">
AND id = 2
</if>
<if test="existFlag == null">
-- 处理字段为null的情况,此处略
</if>
</where>
</select>
既然true、false都需要判断,那么这种写法就相当于:
代码语言:javascript复制if (existFlag) {
// do something 1
} else if (!existFalg){
//do something 2
} else {
//do something 3
}
当if条件变得更多时,代码的逻辑结构显然会变得更臃肿,不易理解。那么我们需要再优化一下。
优化
在Java中,当判断条件变多时,可以使用switch
语句、策略模式等方案优化,那么在MyBatis中可以使用<choose>
进行优化。
MyBatis中的<choose>
标签用于在多个条件中选择第一个满足条件的子句。类似于Java中的switch
语句,<choose>
标签可以根据不同的条件选择执行不同的SQL
子句,提高SQL
语句的灵活性和可读性。
以上代码可以优化为:
代码语言:javascript复制<select id="selectUsersByFlag" resultType="User">
SELECT * FROM users
<where>
<choose>
<when test="existFlag != null and existFlag == true">
AND id = 1
</when>
<when test="existFlag != null and existFlag == false">
AND id = 2
</when>
<otherwise>
and id = 3
</otherwise>
</choose>
</where>
</select>
同样,也可以使用case
、when
优化:
SELECT *
FROM users
WHERE
CASE
WHEN existFlag = true THEN id = 1
WHEN existFlag = false THEN id = 2
ELSE
END
写到最后的一点想法
作为一名程序员,我们的代码首先要保证功能可用,在功能可用的前提下,要保证代码质量可读性、安全、性能等。吾日三省吾身,多思考一下代码如何能写的更好,这要求我们需要不断探索代码的最佳实践。
保持持续学习的态度,每天优化一点点,一点点改进,从而写出更加优雅、高效和安全的代码。
后续内容文章持续更新中…
近期发布。