引言
在电商项目中我们比较常见的问题就是那些未付款的订单,我们需要在一定的时间以后自动关闭交易,如果这个任务是通过人工来完成,工作量是相当可观的,所以我们采用一个定时任务,自动扫面那些订单,然后自动关闭!
有了前面我们对shpring 整合的基础以后,我们在实现这个功能的时候就非常的的简单了
编写job类代码
package com.taotao.store.order.job; import org.joda.time.DateTime; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.context.ApplicationContext; import org.springframework.scheduling.quartz.QuartzJobBean; import com.taotao.store.order.mapper.OrderMapper; /** * 扫描超过2天未付款的订单关闭 */ public class PaymentOrderJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().getJobDataMap() .get("applicationContext"); //时间参数,当前时间向前推2天 applicationContext.getBean(OrderMapper.class).paymentOrderScan(new DateTime().minusDays(2).toDate()); } }
对应的mapper接口代码
package com.taotao.store.order.mapper; import java.util.Date; import org.apache.ibatis.annotations.Param; import com.taotao.store.order.pojo.Order; public interface OrderMapper extends IMapper<Order>{ public void paymentOrderScan(@Param("date") Date date); }
映射文件代码
<update id="paymentOrderScan" parameterType="Date"> UPDATE tb_order SET status = 6, update_time = NOW(), close_time = NOW(), end_time = NOW() WHERE status = 1 AND payment_type = 1 AND create_time <= #{date} </update>
这个job代码的作用就是,按照编写好的任务频率,执行OrderMapper接口中的paymentOrderScan方法,这个方法接受一个时间类型的参数,以当期时间往前推两天。然后执行更新数据库订单状态。
配置文件内容
<!-- 定义任务bean --> <bean name="paymentOrderJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- 指定具体的job类 --> <property name="jobClass" value="com.taotao.store.order.job.PaymentOrderJob" /> <!-- 指定job的名称 --> <property name="name" value="paymentOrder" /> <!-- 指定job的分组 --> <property name="group" value="Order" /> <!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中删除该任务 --> <property name="durability" value="true"/> <!-- 指定spring容器的key,如果不设定在job中的jobmap中是获取不到spring容器的 --> <property name="applicationContextJobDataKey" value="applicationContext"/> </bean> <!-- 定义触发器 --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="paymentOrderJobDetail" /> <!-- 每一分钟执行一次 --> <property name="cronExpression" value="0 0/1 * * * ?" /> </bean> <!-- 定义调度器 --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean>
我们现在的事件频率是每个一分钟执行一次,所以我们关闭订单的误差在一分钟之内,如果对于误差要求比较高的需求,我们可以自行设定执行频率。