对于我的项目中,业务层是必不可少的一环,而除了最根本的对于数据库咱们会进行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.大家能够自行理解一下.