对于我的项目中,业务层是必不可少的一环,而除了最根本的对于数据库咱们会进行Dao层的jdbc增删改查操作之外,还会依据我的项目需要进行各种业务操作,本文次要说一下一种倒计时的业务,相似于购票时对于歹意订单达到工夫的主动删除.
而实现任务调度的形式也有很多,本文次要说的是Java中自带的Timer来实现.
1.构建Timer对象
//1.1构建timer对象Timer timer=new Timer();
第一步是构建Timer对象,这个对象的作用是负责去执行一些调度工作(内置了一个线程和一个工作队列).
2.启动线程执行工作
timer.schedule(new TimerTask() {]\ @Override public void run() { System.out.println("执行工作..."); activityDao.updateState(activity.getId()); timer.cancel(); }}, activity.getEndTime());
如下图所示,Timer的api中有多个schedule办法,咱们这里应用的是第一个,须要传入两个参数
其中TimerTask为工作对象,其中有一个须要重写的办法(run()),run()办法内就是工作须要执行的内容,一旦调用此工作的线程取得了CPU,就会去执行run()
另一个是指定的工夫,这里是activity.getEndTime(),获取的流动对象的完结工夫,要达到的目标是,达到设定的流动完结工夫,通过dao层的办法将流动的状态置为0也就是有效化.
执行完工作后能够执行timer.cancel(),退出任务调度,线程也就会销毁,解放内存.
3.引出问题
因为咱们这里的业务是要在新增流动时,开启这个工作的线程,开始进行倒计时,当达到新增时输出的流动完结工夫主动扭转状态(也就是state参数),这就呈现了一个问题--咱们在新增时,个别id都是设为自增的主键,新增时传入的也就是null,那么咱们怎么对数据库进行操作扭转state的值呢?
这时,因为像新增这种较长的sql语句咱们都是在mapper.xml文件中写的-->在<insert>标签中增加-->useGeneratedKeys="true" keyProperty="id"
设置了这两个参数,咱们就能够通过getId办法拿到咱们须要的id了,代码如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cy.pj.activity.dao.ActivityDao"> <insert id="insertActivity" useGeneratedKeys="true" keyProperty="id" parameterType="com.cy.pj.activity.pojo.Activity"> insert into tb_activity (title,category,startTime,endTime,remark,state,createdUser,createdTime) values (#{title},#{category},#{startTime},#{endTime},#{remark},#{state},#{createdUser},now()) </insert> </mapper>
那么,这两个要害的参数到底是什么含意:
useGeneratedKeys=“true” keyProperty=“id”
useGeneratedKeys设置为 true 时,示意如果插入的表id以自增列为主键,则容许JDBC反对主动生成主键,并可将主动生成的主键id返回。
useGeneratedKeys参数只针对insert语句失效,默认为 false;
keyProperty示意将取得自增主键赋值给参数对象的哪个属性.
当然不只是xml文件中能够应用这两个参数,用注解形式写sql语句也同样能够应用:
须要在@insert注解下加上
@Options(useGeneratedKeys = true,keyProperty = "id")注解即可,含意和xml文件雷同.
4.Timer存在问题
Timer只创立惟一的线程来执行所有timer工作.如果一个timer工作的执行很耗时,会导致其余TimerTask的时效准确性出问题.
Timer的另一个问题在于,如果TimerTask抛出未查看的异样,Timer将会产生无奈意料的行为.Timer线程并不捕捉异样,所以TimerTask抛出的未查看的异样会终止timer线程.这种状况下,Timer也不会再从新复原线程的执行了;它谬误地认为整个Timer被勾销了.
这样来看Timer的问题还很重大,业务少的状况还好说,然而真正工作中,业务必定少不了,所以根本在JDK5.0之后很少有应用Timer了,更多是应用ScheduledExecutor或是第三方框架Quartz.大家能够自行理解一下.