java问题总结
一、mybatis-plus实现时间范围查询
在实际开发中常常需要对数进行时间范围的查询,而大部分的时间范围的给定在同一系统的不同页面需求常常是一致的。比如在仓库列表中查询(当天产生的、一周内的、30天内的),销售的商品(当天产生的、一周内的、30天内的)。总之时间范围常常是不变的,所以封装一个方法是必要的。
✅具体实现的方法如下:
package com.sxty.platform.utils;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.sxty.platform.base.common.DateRange;
import org.apache.poi.ss.formula.functions.T;import java.util.Optional;import static cn.dev33.satoken.SaManager.log;public class QueryWrapperUtils {public static <T> LambdaQueryWrapper<T> buildDateRangeWrapper(String dateRange,SFunction<T, ?> timeColumn) {//定义两个时间用于分类处理DateTime beginOfDay;DateTime endOfDay;//通过fromValue查看枚举类中是否有dateRangeOptional<DateRange> range = DateRange.fromValue(dateRange);//枚举类中不存在,那么就直接返回一个空的if (!range.isPresent()) {log.warn("无法解析的 dateRange 值: {}", dateRange);return new LambdaQueryWrapper<>();}//分类处理赋值给两个日期switch (range.get()) {case TODAY:beginOfDay = DateUtil.beginOfDay(DateUtil.date());endOfDay = DateUtil.endOfDay(DateUtil.date());break;case YESTERDAY:beginOfDay = DateUtil.beginOfDay(DateUtil.yesterday());endOfDay = DateUtil.endOfDay(DateUtil.yesterday());break;case LAST_7_DAYS:beginOfDay = DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -6));endOfDay = DateUtil.endOfDay(DateUtil.date());break;case LAST_30_DAYS:beginOfDay = DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -29));endOfDay = DateUtil.endOfDay(DateUtil.date());break;default:log.warn("未处理的 dateRange 类型: {}", dateRange);return new LambdaQueryWrapper<>();}//返回对应的LambdaQueryWrapperreturn new LambdaQueryWrapper<T>().ge(timeColumn, beginOfDay).le(timeColumn, endOfDay);}
}
✅枚举类如下
package com.sxty.platform.base.common;import java.util.Arrays;
import java.util.Optional;public enum DateRange {TODAY("today"),YESTERDAY("yesterday"),LAST_7_DAYS("last7days"),LAST_30_DAYS("last30days");private final String value;DateRange(String value) {this.value = value;}public String getValue() {return value;}// 新增的方法:通过字符串查找枚举public static Optional<DateRange> fromValue(String value) {return Arrays.stream(values()).filter(dr -> dr.value.equalsIgnoreCase(value)).findFirst();}}
参数说明:
dateRange 日期范围,传递一个字符串,与定义好的Enum进行对比
SFunction<T, R> 是 MyBatis-Plus 提供的一个 函数式接口,用于 Lambda 表达式安全地引用实体类的字段(属性),从而避免直接使用字符串字段名造成的代码不安全和维护困难。
❓SFuntion是干什么用的?
SFunction<T, R>
用于表示:
“从 T 类型对象中提取一个字段 R”,例如:
User::getCreateTime
表示:从 User
实体中获取 createTime
字段。
✅在service方法调用
QueryWrapperUtils.buildDateRangeWrapper(pageUserReq.getDateRange(), User::getCreateTime);