示例:
要查询3月、4月、5月、6月这四个月的所有数据(以7月18日为当前时间),核心是精准界定这四个月的时间范围,避免因“最近4个月”的相对时间计算导致边界误差。以下是基于 MyBatis-Plus 的具体实现,重点解决日期范围的准确界定:

1. 明确时间范围

以“今天是7月18日”为例,目标月份的时间范围是:

  • 3月2024-03-01 00:00:002024-03-31 23:59:59
  • 4月2024-04-01 00:00:002024-04-30 23:59:59
  • 5月2024-05-01 00:00:002024-05-31 23:59:59
  • 6月2024-06-01 00:00:002024-06-30 23:59:59

整体可合并为:2024-03-01 00:00:002024-06-30 23:59:59

2. 代码实现(Java 8+ 推荐方案)

使用 LocalDateTimejava.time 包处理日期,避免 DateCalendar 的繁琐操作,精准计算月份的起止时间:

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

@Service
public class YourService {

    @Autowired
    private YourMapper yourMapper;

    /**
     * 查询3、4、5、6月份的所有数据(以7月为当前月为例)
     */
    public List<YourEntity> getMarchToJuneData() {
        // 1. 确定目标年份(这里以当前年为例,若需固定年份可直接写死,如 2024)
        int year = LocalDateTime.now().getYear();

        // 2. 计算3月1日 00:00:00
        LocalDateTime marchStart = LocalDateTime.of(
            year, 3, 1, 0, 0, 0
        );
        // 3. 计算6月最后一天 23:59:59
        YearMonth june = YearMonth.of(year, 6); // 获取6月
        int lastDayOfJune = june.lengthOfMonth(); // 6月的最后一天(30)
        LocalDateTime juneEnd = LocalDateTime.of(
            year, 6, lastDayOfJune, 23, 59, 59
        );

        // 4. 转换为 Date 类型(适配实体类的 Date 字段)
        Date startDate = Date.from(marchStart.atZone(ZoneId.systemDefault()).toInstant());
        Date endDate = Date.from(juneEnd.atZone(ZoneId.systemDefault()).toInstant());

        // 5. 构建查询条件:时间字段 between 开始时间 and 结束时间
        LambdaQueryWrapper<YourEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.between(YourEntity::getCreateTime, startDate, endDate);

        // 6. 执行查询
        return yourMapper.selectList(queryWrapper);
    }
}

3. 关键说明

  • 日期范围精准性:通过 YearMonth.lengthOfMonth() 动态获取月份的最后一天(如6月30天、3月31天),避免硬编码导致的月份天数错误。
  • 格式无需手动处理:MyBatis-Plus 会自动将 Java 的 Date 类型与数据库的 Date 字段映射,无需手动转换为字符串(如 yyyy-MM-dd),避免格式不匹配问题。
  • 通用性扩展:若需要动态适配“当前月的前4个月”(而非固定3-6月),可通过 LocalDateTime.now().minusMonths(4) 计算起始月份,再调整起止时间。

4. 兼容旧版本 Java(无 LocalDateTime)

若使用 Java 7 及以下,可通过 Calendar 实现:

import java.util.Calendar;
import java.util.Date;

// 计算3月1日 00:00:00
Calendar marchStartCal = Calendar.getInstance();
marchStartCal.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
marchStartCal.set(Calendar.MONTH, Calendar.MARCH); // 3月(Calendar.MARCH=2)
marchStartCal.set(Calendar.DAY_OF_MONTH, 1);
marchStartCal.set(Calendar.HOUR_OF_DAY, 0);
marchStartCal.set(Calendar.MINUTE, 0);
marchStartCal.set(Calendar.SECOND, 0);
Date startDate = marchStartCal.getTime();

// 计算6月最后一天 23:59:59
Calendar juneEndCal = Calendar.getInstance();
juneEndCal.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
juneEndCal.set(Calendar.MONTH, Calendar.JUNE); // 6月(Calendar.JUNE=5)
juneEndCal.set(Calendar.DAY_OF_MONTH, juneEndCal.getActualMaximum(Calendar.DAY_OF_MONTH)); // 最后一天
juneEndCal.set(Calendar.HOUR_OF_DAY, 23);
juneEndCal.set(Calendar.MINUTE, 59);
juneEndCal.set(Calendar.SECOND, 59);
Date endDate = juneEndCal.getTime();

// 查询条件(同上)
LambdaQueryWrapper<YourEntity> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.between(YourEntity::getCreateTime, startDate, endDate);

通过以上方式,无论数据库 Date 字段是 DATE(仅日期)还是 DATETIME(日期+时间)类型,都能准确筛选出目标月份的所有数据,无需担心日期格式转换问题。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐