研发踩坑实录
1.遇到的问题:数据库条件查询失效。
2.数据库使用环境:mybatis-plus
3.查询入参类ProductQuery :
存在两个查询字段status,download,都为Integer类型。
import java.math.BigDecimal;
import java.util.List;/*** 产品查询条件对象*/
public class ProductQuery {/*** 产品名称(模糊查询)*/private String name;/*** 品牌ID*/private Integer brandId;/*** 最低价格*/private BigDecimal minPrice;/*** 最高价格*/private BigDecimal maxPrice;/*** 分类ID列表*/private List<Integer> categoryIds;/*** 状态*/private Integer status;/*** 下载量*/private Integer download;// 构造方法public ProductQuery() {}// Getter 和 Setter 方法public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getBrandId() {return brandId;}public void setBrandId(Integer brandId) {this.brandId = brandId;}public BigDecimal getMinPrice() {return minPrice;}public void setMinPrice(BigDecimal minPrice) {this.minPrice = minPrice;}public BigDecimal getMaxPrice() {return maxPrice;}public void setMaxPrice(BigDecimal maxPrice) {this.maxPrice = maxPrice;}public List<Integer> getCategoryIds() {return categoryIds;}public void setCategoryIds(List<Integer> categoryIds) {this.categoryIds = categoryIds;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public Integer getDownload() {return download;}public void setDownload(Integer download) {this.download = download;}@Overridepublic String toString() {return "ProductQuery{" +"name='" + name + '\'' +", brandId=" + brandId +", minPrice=" + minPrice +", maxPrice=" + maxPrice +", categoryIds=" + categoryIds +", status=" + status +", download=" + download +'}';}
}
4.测试工具:postman 查询 download=0的情况。并未生效。查询download= 1的条件生效了。在试了另一个字段status = 1条件生效了。
5.数据库XmL文件如下:
对应where条件的sql语句片段如下:
<select id="selectByQuery" parameterType="ProductQuery" resultMap="productResultMap">SELECT * FROM products<where><!-- 原有的条件 --><if test="name != null and name != ''">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="brandId != null">AND brand_id = #{brandId}</if><if test="minPrice != null">AND price >= #{minPrice}</if><if test="maxPrice != null">AND price <= #{maxPrice}</if><if test="categoryIds != null and categoryIds.size() > 0">AND category_id IN<foreach collection="categoryIds" item="cid" open="(" separator="," close=")">#{cid}</foreach></if><!-- 新增的 status 字段条件:精确匹配 --><if test="status != null and status != ''">AND status = #{status}</if><!-- 新增的 download 字段条件:精确匹配 --><if test="download != null download != ''">AND download = #{download}</if></where>ORDER BY create_time DESC
</select>
6.问题排查
status和download不同的地方在于staus值都为正数,而downlaod可以从0开始。所以测试一下status = 0的查询,mybatis也直接无视了这个条件把所有的数据查询出来了。说明问题在于这两个字段查询的值为0时都失效了。(可以看预编译sql,这两个字段都没生成占位符)。再回到动态sql,说明test条件没有成立,0与null或' '匹配了。我们去掉其中一个测试,组后发现去掉=' '的情况,查询生效了。
<!-- 新增的 status 字段条件:精确匹配 --><if test="status != null">AND status = #{status}</if><!-- 新增的 download 字段条件:精确匹配 --><if test="download != null">AND download = #{download}</if>
7.总结
对于Integer字段test条件不要加上等空字符串的判断,不然它会查询为0时与空字符串比较会有问题,显然在我的代码中把0当成空字符串了。字符串类型的字段才需要加上是否为空的判断。