今天在研发功能时,进行单表查询条件编写时,产品经理在需求文档中写一句:提供等于备案时间的查询功能。本项目的基础架构时:SpringBoot + SpringBoot Alibaba Cloud + MyBatis 3 + MyBatis Plus。
在DaoImpl 实现,直接使用LambdaQueryWrappe 中的函数式接口SFunction,编写相关逻辑代码。
报错代码
public List<BizUser> query(BizUserQueryBO queryBO){
// 自定义SFunction 时间函数
SFunction<BizUser, String> dataFunction = it -> "date_format(filing_time, '%Y-%m-%d')"
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(StringUtils.isNotBlank(queryBO.getTid), BizUser::getTid, queryBO.getTid)
...... 省略其他条件构造
// 报错代码片段
lambdaQueryWrapper.eq(StringUtils.isNotBlank(queryBO.nowTime), dataFunction , queryBO.nowTime)
}
原因解析:
MyBatisPlus的条件构造器不会真的去调用SFunction这个函数式接口而是只解析实际的方法名.如果解析的是Lambbda表达式,那么方法名跟数据库的列名匹配不上就会报错; 如果是方法引用那么方法名通过is/gey/set规则就能找到相应的字段名然后在根据规则转换成数据库表的列名.
注意: 如果字段名和列名不符合缺省的转换规则,那么必需在字段名上加上
@TableField("列名")
注解来明确表明实际的列名.
现在 BizUserQueryBO 封装请求参数对象中的nowTime 字段在数据库表中没有对应的字段,那应该如何解决,可以使用LambadQueryWrapper.apply ()方法。
正确代码:
public List<BizUser> query(BizUserQueryBO queryBO){
// 修改代码片段一
// 自定义时间函数字符串
String dataFunction = "date_format(filing_time, '%Y-%m-%d')";
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(StringUtils.isNotBlank(queryBO.getTid), BizUser::getTid, queryBO.getTid)
...... 省略其他条件构造
// 修改代码片段二
lambdaQueryWrapper.apply(StringUtils.isNotBlank(queryBO.nowTime), dataFunction , queryBO.nowTime)
}