场景描述:
在生产环境中,有时要临时调整定时任务时间,或者禁用/启用定时任务; 以前都是修改cron表达式后重启项目; 总是感觉这个操作有点麻烦,不够方便, 于是,想实现一个动态的配置处理!!!
功能实现:
1.代码结构:
2.代码实现:
2.1 创建定时任务配置表
CREATE TABLE `scheduled` ( `id` int(11) NOT NULL AUTO_INCREMENT, `task_key` varchar(127) NOT NULL COMMENT '任务key值(使用bean名称)', `name` varchar(127) DEFAULT NULL COMMENT '任务名称', `cron` varchar(63) NOT NULL COMMENT '任务表达式', `status` int(2) DEFAULT '0' COMMENT '状态(0.禁用; 1.启用)', `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间', `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uniqu_task_key` (`task_key`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='定时任务配置表';
2.2 java代码
2.2.1 创建定时任务线程池
package com.yihaocard.main.scheduled.config; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** * @ClassName ScheduledTaskConfig * @Description 创建定时任务线程池,初始化任务Map * @Author lv617 * @Date 2020/9/8 10:39 * @Version 1.0 */ @Slf4j @Configuration public class ScheduledTaskConfig { @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { log.info("创建定时任务调度线程池 start"); ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(20); threadPoolTaskScheduler.setThreadNamePrefix("taskExecutor-"); //用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean,这样这些异步任务的销毁就会先于Redis线程池的销毁。 threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); //该方法用来设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。 threadPoolTaskScheduler.setAwaitTerminationSeconds(60); log.info("创建定时任务调度线程池 end"); return threadPoolTaskScheduler; } }
2.2.2 初始化启动定时任务
package com.yihaocard.main.scheduled.config; import com.yihaocard.main.scheduled.ScheduledTaskService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; /** * @ClassName ScheduledTaskRunner * @Description 项目启动完毕后开启需要自启的任务 * @Author lv617 * @Date 2020/9/8 11:35 * @Version 1.0 */ @Slf4j @Component public class ScheduledTaskRunner implements ApplicationRunner { @Autowired private ScheduledTaskService scheduledTaskService; /** * 程序启动完毕后,需要自启的任务 */ @Override public void run(ApplicationArguments applicationArguments){ log.info(" >>>>>> 项目启动完毕, 开启 => 需要自启的任务 开始!"); scheduledTaskService.initAllTask(); log.info(" >>>>>> 项目启动完毕, 开启 => 需要自启的任务 结束!"); } }
2.2.3 定时任务状态枚举类
package com.yihaocard.main.scheduled.constant; /** * Created by lynn on 2018/4/17. */ public enum ScheduledStatus { ENABLE(0, "禁用"), DISABLE(1, "启用"); private int code; private String name; ScheduledStatus(int code, String name){ this.code = code; this.name = name; } public static ScheduledStatus getByCode(int code){ for (ScheduledStatus st : values()) { if(code == st.getCode()) return st; } return null; } public int getCode() { return code; } public String getName() { return name; } }
2.2.4 定时任务公共父接口
package com.yihaocard.main.scheduled; /** * @ClassName ScheduledTaskJob * @Description 创建调度任务公共父接口 * @Author lv617 * @Date 2020/9/8 10:43 * @Version 1.0 */ public interface ScheduledTaskJob extends Runnable{ }
2.2.5 定时任务实现类(处理具体的定时任务逻辑)
注:本文档由于篇幅限制,只写两个空的实现类作为演示用;
package com.yihaocard.main.scheduled.impl; import com.yihaocard.main.scheduled.ScheduledTaskJob; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** * @ClassName ScheduledTaskJob01 * @Description 测试类01 * @Author lv617 * @Date 2020/9/8 10:46 * @Version 1.0 */ @Slf4j @Service public class ScheduledTaskJob01 implements ScheduledTaskJob { @Override public void run() { // TODO 要处理的业务逻辑 log.info("ScheduledTask => 01 run 当前线程名称 {} ", Thread.currentThread().getName()); } }
package com.yihaocard.main.scheduled.impl; import com.yihaocard.main.scheduled.ScheduledTaskJob; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** * @ClassName ScheduledTaskJob01 * @Description 测试类02 * @Author lv617 * @Date 2020/9/8 10:46 * @Version 1.0 */ @Slf4j @Service public class ScheduledTaskJob02 implements ScheduledTaskJob { @Override public void run() { // TODO 要处理的业务逻辑 log.info("ScheduledTask => 02 run 当前线程名称 {} ", Thread.currentThread().getName()); } }
2.2.6 定时任务管理接口(重要)
package com.yihaocard.main.scheduled; import com.yihaocard.main.module.scheduled.model.Scheduled; /** * @ClassName ScheduledTaskService * @Description 定时任务接口 * @Author lv617 * @Date 2020/9/8 10:51 * @Version 1.0 */ public interface ScheduledTaskService { /** * 根据任务key 启动任务 */ Boolean start(String taskKey, Scheduled scheduled); /** * 根据任务key 停止任务 */ Boolean stop(String taskKey); /** * 根据任务key 重启任务 */ Boolean restart(String taskKey, Scheduled scheduled); /** * 初始化 ==> 启动所有正常状态的任务 */ void initAllTask(); }
2.2.7 定时任务管理实现类(重要)
package com.yihaocard.main.scheduled.impl; import com.yihaocard.main.module.scheduled.dao.ScheduledMapper; import com.yihaocard.main.module.scheduled.model.Scheduled; import com.yihaocard.main.module.scheduled.model.ScheduledExample; import com.yihaocard.main.scheduled.ScheduledTaskJob; import com.yihaocard.main.scheduled.ScheduledTaskService; import com.yihaocard.main.scheduled.constant.ScheduledStatus; import com.yihaocard.main.springboot.SpringContext; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.TriggerContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.CronTrigger; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.locks.ReentrantLock; /** * @ClassName ScheduledTaskServiceImpl * @Description 定时任务实现 * @Author lv617 * @Date 2020/9/8 10:53 * @Version 1.0 */ @Slf4j @Service public class ScheduledTaskServiceImpl implements ScheduledTaskService { @Value("${task.enabled}") private Boolean taskEnable; /** * 可重入锁 */ private ReentrantLock lock = new ReentrantLock(); /** * 定时任务线程池 */ @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; /** * 存放已经启动的任务map */ private Map<String, ScheduledFuture> scheduledFutureMap = new ConcurrentHashMap<>(); @Autowired private ScheduledMapper scheduledMapper; /** * 描述: 根据任务key 启动任务 * * @param taskKey * @param scheduled * @return java.lang.Boolean * @author lv617 * @date 2020/9/24 11:16 */ @Override public Boolean start(String taskKey, Scheduled scheduled) { log.info(">>>>>> 启动任务 {} 开始 >>>>>>", taskKey); //添加锁放一个线程启动,防止多人启动多次 lock.lock(); log.info(">>>>>> 添加任务启动锁完毕"); try { //校验是否已经启动 if (this.isStart(taskKey)) { log.info(">>>>>> 当前任务已经启动,无需重复启动!"); return false; } //查询配置 if(scheduled == null) scheduled = this.getByTaskKey(taskKey); if(scheduled == null) return false; //启动任务 this.doStartTask(scheduled); } finally { // 释放锁 lock.unlock(); log.info(">>>>>> 释放任务启动锁完毕"); } log.info(">>>>>> 启动任务 {} 结束 >>>>>>", taskKey); return true; } /** * 描述: 查询定时任务配置参数 * * @param taskKey * @return com.yihaocard.main.module.scheduled.model.Scheduled * @author lv617 * @date 2020/9/24 11:14 */ private Scheduled getByTaskKey(String taskKey) { ScheduledExample scheduledExample = new ScheduledExample(); scheduledExample.createCriteria() .andStatusEqualTo(ScheduledStatus.DISABLE.getCode()) .andTaskKeyEqualTo(taskKey); List<Scheduled> scheduleds = scheduledMapper.selectByExample(scheduledExample); if(scheduleds == null || scheduleds.size() < 1) return null; return scheduleds.get(0); } /** * 描述: 根据 key 停止任务 * * @param taskKey * @return java.lang.Boolean * @author lv617 * @date 2020/9/24 11:17 */ @Override public Boolean stop(String taskKey) { log.info(">>>>>> 进入停止任务 {} >>>>>>", taskKey); //当前任务实例是否存在 boolean taskStartFlag = scheduledFutureMap.containsKey(taskKey); log.info(">>>>>> 当前任务实例是否存在 {}", taskStartFlag); if (taskStartFlag) { //获取任务实例 ScheduledFuture scheduledFuture = scheduledFutureMap.get(taskKey); //关闭实例 boolean cancel = scheduledFuture.cancel(true); log.info("cancel:{}", cancel); //删除关闭的任务实例 scheduledFutureMap.remove(taskKey); } log.info(">>>>>> 结束停止任务 {} >>>>>>", taskKey); return taskStartFlag; } /** * 描述: 根据任务key 重启任务 * * @param taskKey * @param scheduled * @return java.lang.Boolean * @author lv617 * @date 2020/9/24 11:18 */ @Override public Boolean restart(String taskKey, Scheduled scheduled) { log.info(">>>>>> 进入重启任务 {} >>>>>>", taskKey); //先停止 this.stop(taskKey); //查询配置 if(scheduled == null) scheduled = this.getByTaskKey(taskKey); if(scheduled == null) return false; //再启动 return this.start(taskKey,scheduled); } /** * 初始化 ==> 启动所有正常状态的任务 */ @Override public void initAllTask() { if(!taskEnable){ log.info("配置文件禁用了定时任务----"); return; } ScheduledExample scheduledExample = new ScheduledExample(); scheduledExample.createCriteria() .andStatusEqualTo(ScheduledStatus.DISABLE.getCode()); List<Scheduled> scheduleds = scheduledMapper.selectByExample(scheduledExample); log.info("初始化 ==> 启动所有正常状态的任务开始 !size={}", scheduleds == null ? 0 : scheduleds.size()); if (scheduleds == null || scheduleds.size() < 1) { return; } for (Scheduled scheduled : scheduleds) { //任务 key String taskKey = scheduled.getTaskKey(); //校验是否已经启动 if (this.isStart(taskKey)) { // 重启任务 this.restart(taskKey,scheduled); } else { // 启动任务 this.doStartTask(scheduled); } } log.info("初始化 ==> 启动所有正常状态的任务结束 !"); } /** * 执行启动任务 */ private void doStartTask(Scheduled scheduled) { if (scheduled == null) return; //任务key String taskKey = scheduled.getTaskKey(); //定时表达式 String taskCron = scheduled.getCron(); //获取需要定时调度的接口 ScheduledTaskJob scheduledTaskJob = (ScheduledTaskJob) SpringContext.getBean(taskKey); log.info(">>>>>> 任务 [ {} ] ,cron={}", scheduled.getName(), taskCron); ScheduledFuture scheduledFuture = threadPoolTaskScheduler.schedule(scheduledTaskJob, (TriggerContext triggerContext) -> new CronTrigger(taskCron).nextExecutionTime(triggerContext)); //将启动的任务放入 map scheduledFutureMap.put(taskKey, scheduledFuture); } /** * 任务是否已经启动 */ private Boolean isStart(String taskKey) { //校验是否已经启动 if (scheduledFutureMap.containsKey(taskKey)) { if (!scheduledFutureMap.get(taskKey).isCancelled()) { return true; } } return false; } }
3. 效果展示
3.1 定时任务初始配置
3.2 启动项目
3.3 后台管理修改定时任务
注:后台定时任务管理页面就是展示数据库scheduled表数据,提交修改就是更新数据库数据并调用ScheduledTaskService类的restart()方法,这里的简单逻辑就不在赘述了!
3.3.1 修改前
3.3.2 编辑修改
3.3.3 提交修改
至此,已完整的实现了动态的定时任务修改/重启/关闭的功能!
4. 补充Scheduled和ScheduledExample两个类
package com.yihaocard.main.module.scheduled.model; import java.time.LocalDateTime; import lombok.Data; import lombok.experimental.Accessors; /** * scheduled */ @Accessors(chain = true) @Data public class Scheduled { /** * scheduled.id */ private Integer id; /** * scheduled.task_key * 任务key值(使用bean名称) */ private String taskKey; /** * scheduled.name * 任务名称 */ private String name; /** * scheduled.cron * 任务表达式 */ private String cron; /** * scheduled.status * 状态(0.禁用; 1.启用) */ private Integer status; /** * scheduled.create_time * 创建时间 */ private LocalDateTime createTime; /** * scheduled.update_time * 更新时间 */ private LocalDateTime updateTime; }
package com.yihaocard.main.module.scheduled.model; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; public class ScheduledExample { /** * scheduled */ protected String orderByClause; /** * scheduled */ protected boolean distinct; /** * scheduled */ protected List<Criteria> oredCriteria; /** * This method corresponds to the database table scheduled */ public ScheduledExample() { oredCriteria = new ArrayList<Criteria>(); } /** * This method corresponds to the database table scheduled */ public void setOrderByClause(String orderByClause) { this.orderByClause = orderByClause; } /** * This method corresponds to the database table scheduled */ public String getOrderByClause() { return orderByClause; } /** * This method corresponds to the database table scheduled */ public void setDistinct(boolean distinct) { this.distinct = distinct; } /** * This method corresponds to the database table scheduled */ public boolean isDistinct() { return distinct; } /** * This method corresponds to the database table scheduled */ public List<Criteria> getOredCriteria() { return oredCriteria; } /** * This method corresponds to the database table scheduled */ public void or(Criteria criteria) { oredCriteria.add(criteria); } /** * This method corresponds to the database table scheduled */ public Criteria or() { Criteria criteria = createCriteriaInternal(); oredCriteria.add(criteria); return criteria; } /** * This method corresponds to the database table scheduled */ public Criteria createCriteria() { Criteria criteria = createCriteriaInternal(); if (oredCriteria.size() == 0) { oredCriteria.add(criteria); } return criteria; } /** * This method corresponds to the database table scheduled */ protected Criteria createCriteriaInternal() { Criteria criteria = new Criteria(); return criteria; } /** * This method corresponds to the database table scheduled */ public void clear() { oredCriteria.clear(); orderByClause = null; distinct = false; } /** * This class corresponds to the database table scheduled */ protected abstract static class GeneratedCriteria { protected List<Criterion> criteria; protected GeneratedCriteria() { super(); criteria = new ArrayList<Criterion>(); } public boolean isValid() { return criteria.size() > 0; } public List<Criterion> getAllCriteria() { return criteria; } public List<Criterion> getCriteria() { return criteria; } protected void addCriterion(String condition) { if (condition == null) { throw new RuntimeException("Value for condition cannot be null"); } criteria.add(new Criterion(condition)); } protected void addCriterion(String condition, Object value, String property) { if (value == null) { throw new RuntimeException("Value for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value)); } protected void addCriterion(String condition, Object value1, Object value2, String property) { if (value1 == null || value2 == null) { throw new RuntimeException("Between values for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value1, value2)); } public Criteria andIdIsNull() { addCriterion("id is null"); return (Criteria) this; } public Criteria andIdIsNotNull() { addCriterion("id is not null"); return (Criteria) this; } public Criteria andIdEqualTo(Integer value) { addCriterion("id =", value, "id"); return (Criteria) this; } public Criteria andIdNotEqualTo(Integer value) { addCriterion("id <>", value, "id"); return (Criteria) this; } public Criteria andIdGreaterThan(Integer value) { addCriterion("id >", value, "id"); return (Criteria) this; } public Criteria andIdGreaterThanOrEqualTo(Integer value) { addCriterion("id >=", value, "id"); return (Criteria) this; } public Criteria andIdLessThan(Integer value) { addCriterion("id <", value, "id"); return (Criteria) this; } public Criteria andIdLessThanOrEqualTo(Integer value) { addCriterion("id <=", value, "id"); return (Criteria) this; } public Criteria andIdIn(List<Integer> values) { addCriterion("id in", values, "id"); return (Criteria) this; } public Criteria andIdNotIn(List<Integer> values) { addCriterion("id not in", values, "id"); return (Criteria) this; } public Criteria andIdBetween(Integer value1, Integer value2) { addCriterion("id between", value1, value2, "id"); return (Criteria) this; } public Criteria andIdNotBetween(Integer value1, Integer value2) { addCriterion("id not between", value1, value2, "id"); return (Criteria) this; } public Criteria andTaskKeyIsNull() { addCriterion("task_key is null"); return (Criteria) this; } public Criteria andTaskKeyIsNotNull() { addCriterion("task_key is not null"); return (Criteria) this; } public Criteria andTaskKeyEqualTo(String value) { addCriterion("task_key =", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyNotEqualTo(String value) { addCriterion("task_key <>", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyGreaterThan(String value) { addCriterion("task_key >", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyGreaterThanOrEqualTo(String value) { addCriterion("task_key >=", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyLessThan(String value) { addCriterion("task_key <", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyLessThanOrEqualTo(String value) { addCriterion("task_key <=", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyLike(String value) { addCriterion("task_key like", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyNotLike(String value) { addCriterion("task_key not like", value, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyIn(List<String> values) { addCriterion("task_key in", values, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyNotIn(List<String> values) { addCriterion("task_key not in", values, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyBetween(String value1, String value2) { addCriterion("task_key between", value1, value2, "taskKey"); return (Criteria) this; } public Criteria andTaskKeyNotBetween(String value1, String value2) { addCriterion("task_key not between", value1, value2, "taskKey"); return (Criteria) this; } public Criteria andNameIsNull() { addCriterion("name is null"); return (Criteria) this; } public Criteria andNameIsNotNull() { addCriterion("name is not null"); return (Criteria) this; } public Criteria andNameEqualTo(String value) { addCriterion("name =", value, "name"); return (Criteria) this; } public Criteria andNameNotEqualTo(String value) { addCriterion("name <>", value, "name"); return (Criteria) this; } public Criteria andNameGreaterThan(String value) { addCriterion("name >", value, "name"); return (Criteria) this; } public Criteria andNameGreaterThanOrEqualTo(String value) { addCriterion("name >=", value, "name"); return (Criteria) this; } public Criteria andNameLessThan(String value) { addCriterion("name <", value, "name"); return (Criteria) this; } public Criteria andNameLessThanOrEqualTo(String value) { addCriterion("name <=", value, "name"); return (Criteria) this; } public Criteria andNameLike(String value) { addCriterion("name like", value, "name"); return (Criteria) this; } public Criteria andNameNotLike(String value) { addCriterion("name not like", value, "name"); return (Criteria) this; } public Criteria andNameIn(List<String> values) { addCriterion("name in", values, "name"); return (Criteria) this; } public Criteria andNameNotIn(List<String> values) { addCriterion("name not in", values, "name"); return (Criteria) this; } public Criteria andNameBetween(String value1, String value2) { addCriterion("name between", value1, value2, "name"); return (Criteria) this; } public Criteria andNameNotBetween(String value1, String value2) { addCriterion("name not between", value1, value2, "name"); return (Criteria) this; } public Criteria andCronIsNull() { addCriterion("cron is null"); return (Criteria) this; } public Criteria andCronIsNotNull() { addCriterion("cron is not null"); return (Criteria) this; } public Criteria andCronEqualTo(String value) { addCriterion("cron =", value, "cron"); return (Criteria) this; } public Criteria andCronNotEqualTo(String value) { addCriterion("cron <>", value, "cron"); return (Criteria) this; } public Criteria andCronGreaterThan(String value) { addCriterion("cron >", value, "cron"); return (Criteria) this; } public Criteria andCronGreaterThanOrEqualTo(String value) { addCriterion("cron >=", value, "cron"); return (Criteria) this; } public Criteria andCronLessThan(String value) { addCriterion("cron <", value, "cron"); return (Criteria) this; } public Criteria andCronLessThanOrEqualTo(String value) { addCriterion("cron <=", value, "cron"); return (Criteria) this; } public Criteria andCronLike(String value) { addCriterion("cron like", value, "cron"); return (Criteria) this; } public Criteria andCronNotLike(String value) { addCriterion("cron not like", value, "cron"); return (Criteria) this; } public Criteria andCronIn(List<String> values) { addCriterion("cron in", values, "cron"); return (Criteria) this; } public Criteria andCronNotIn(List<String> values) { addCriterion("cron not in", values, "cron"); return (Criteria) this; } public Criteria andCronBetween(String value1, String value2) { addCriterion("cron between", value1, value2, "cron"); return (Criteria) this; } public Criteria andCronNotBetween(String value1, String value2) { addCriterion("cron not between", value1, value2, "cron"); return (Criteria) this; } public Criteria andStatusIsNull() { addCriterion("status is null"); return (Criteria) this; } public Criteria andStatusIsNotNull() { addCriterion("status is not null"); return (Criteria) this; } public Criteria andStatusEqualTo(Integer value) { addCriterion("status =", value, "status"); return (Criteria) this; } public Criteria andStatusNotEqualTo(Integer value) { addCriterion("status <>", value, "status"); return (Criteria) this; } public Criteria andStatusGreaterThan(Integer value) { addCriterion("status >", value, "status"); return (Criteria) this; } public Criteria andStatusGreaterThanOrEqualTo(Integer value) { addCriterion("status >=", value, "status"); return (Criteria) this; } public Criteria andStatusLessThan(Integer value) { addCriterion("status <", value, "status"); return (Criteria) this; } public Criteria andStatusLessThanOrEqualTo(Integer value) { addCriterion("status <=", value, "status"); return (Criteria) this; } public Criteria andStatusIn(List<Integer> values) { addCriterion("status in", values, "status"); return (Criteria) this; } public Criteria andStatusNotIn(List<Integer> values) { addCriterion("status not in", values, "status"); return (Criteria) this; } public Criteria andStatusBetween(Integer value1, Integer value2) { addCriterion("status between", value1, value2, "status"); return (Criteria) this; } public Criteria andStatusNotBetween(Integer value1, Integer value2) { addCriterion("status not between", value1, value2, "status"); return (Criteria) this; } public Criteria andCreateTimeIsNull() { addCriterion("create_time is null"); return (Criteria) this; } public Criteria andCreateTimeIsNotNull() { addCriterion("create_time is not null"); return (Criteria) this; } public Criteria andCreateTimeEqualTo(LocalDateTime value) { addCriterion("create_time =", value, "createTime"); return (Criteria) this; } public Criteria andCreateTimeNotEqualTo(LocalDateTime value) { addCriterion("create_time <>", value, "createTime"); return (Criteria) this; } public Criteria andCreateTimeGreaterThan(LocalDateTime value) { addCriterion("create_time >", value, "createTime"); return (Criteria) this; } public Criteria andCreateTimeGreaterThanOrEqualTo(LocalDateTime value) { addCriterion("create_time >=", value, "createTime"); return (Criteria) this; } public Criteria andCreateTimeLessThan(LocalDateTime value) { addCriterion("create_time <", value, "createTime"); return (Criteria) this; } public Criteria andCreateTimeLessThanOrEqualTo(LocalDateTime value) { addCriterion("create_time <=", value, "createTime"); return (Criteria) this; } public Criteria andCreateTimeIn(List<LocalDateTime> values) { addCriterion("create_time in", values, "createTime"); return (Criteria) this; } public Criteria andCreateTimeNotIn(List<LocalDateTime> values) { addCriterion("create_time not in", values, "createTime"); return (Criteria) this; } public Criteria andCreateTimeBetween(LocalDateTime value1, LocalDateTime value2) { addCriterion("create_time between", value1, value2, "createTime"); return (Criteria) this; } public Criteria andCreateTimeNotBetween(LocalDateTime value1, LocalDateTime value2) { addCriterion("create_time not between", value1, value2, "createTime"); return (Criteria) this; } public Criteria andUpdateTimeIsNull() { addCriterion("update_time is null"); return (Criteria) this; } public Criteria andUpdateTimeIsNotNull() { addCriterion("update_time is not null"); return (Criteria) this; } public Criteria andUpdateTimeEqualTo(LocalDateTime value) { addCriterion("update_time =", value, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeNotEqualTo(LocalDateTime value) { addCriterion("update_time <>", value, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeGreaterThan(LocalDateTime value) { addCriterion("update_time >", value, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeGreaterThanOrEqualTo(LocalDateTime value) { addCriterion("update_time >=", value, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeLessThan(LocalDateTime value) { addCriterion("update_time <", value, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeLessThanOrEqualTo(LocalDateTime value) { addCriterion("update_time <=", value, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeIn(List<LocalDateTime> values) { addCriterion("update_time in", values, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeNotIn(List<LocalDateTime> values) { addCriterion("update_time not in", values, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeBetween(LocalDateTime value1, LocalDateTime value2) { addCriterion("update_time between", value1, value2, "updateTime"); return (Criteria) this; } public Criteria andUpdateTimeNotBetween(LocalDateTime value1, LocalDateTime value2) { addCriterion("update_time not between", value1, value2, "updateTime"); return (Criteria) this; } } /** * scheduled */ public static class Criteria extends GeneratedCriteria { protected Criteria() { super(); } } /** * This class corresponds to the database table scheduled */ public static class Criterion { private String condition; private Object value; private Object secondValue; private boolean noValue; private boolean singleValue; private boolean betweenValue; private boolean listValue; private String typeHandler; public String getCondition() { return condition; } public Object getValue() { return value; } public Object getSecondValue() { return secondValue; } public boolean isNoValue() { return noValue; } public boolean isSingleValue() { return singleValue; } public boolean isBetweenValue() { return betweenValue; } public boolean isListValue() { return listValue; } public String getTypeHandler() { return typeHandler; } protected Criterion(String condition) { super(); this.condition = condition; this.typeHandler = null; this.noValue = true; } protected Criterion(String condition, Object value, String typeHandler) { super(); this.condition = condition; this.value = value; this.typeHandler = typeHandler; if (value instanceof List<?>) { this.listValue = true; } else { this.singleValue = true; } } protected Criterion(String condition, Object value) { this(condition, value, null); } protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { super(); this.condition = condition; this.value = value; this.secondValue = secondValue; this.typeHandler = typeHandler; this.betweenValue = true; } protected Criterion(String condition, Object value, Object secondValue) { this(condition, value, secondValue, null); } } }
下一个:数据结构详解·一树的初步