定时任务很常用,在此写个例子做一下展示。
例子很简单,利用servlet的load-on-startup配置在init方法中启动一个定时器。
在需要的时间点启动任务即可。
web.xml配置
<!-- lsy测试 --> <servlet> <servlet-name>lsytestServlet</servlet-name> <servlet-class>com.xxx.lsy.LsyTestServlet</servlet-class> <init-param> <param-name>dataSourceName</param-name> <param-value>data1</param-value> </init-param> <load-on-startup>5</load-on-startup> </servlet> <servlet-mapping> <servlet-name>lsytestServlet</servlet-name> <url-pattern>/lsytestServlet</url-pattern> </servlet-mapping>
定时任务一般会和数据库打交道,这里我简单写了个数据库操作的任务,所以把数据库jdbc的部分封装了一下。
package com.sunyard.hawaii.lsy; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.naming.Context; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.sunyard.hawaii.lsy.sql.LsySqlUtil; import com.sunyard.hawaii.lsy.sql.TimerTaskOne; /** * 内容1: * 利用servlet配置中的load-on-startup在web应用启动后,servlet调用init方法。 * 在这个过程中可以初始化数据源,同时可以做一些其他操作,例如启动一个定时任务等。 * 注意load-on-startup范围是1-10,数字越大,优先级越小,启动越往后。 * * 内容2: * 把jdbc结果集封装到一个map中,包括字段名和值 * 数据库使用db2 * * @author lushuaiyin * */ public class LsyTestServlet extends HttpServlet { public ServletContext servletContext=null; public HttpServletRequest httpServletRequest=null; public Context ctx = null; public void init() throws ServletException { System.out.println("LsyTestServlet init --------------------------------"); this.servletContext= this.getServletContext(); //获取web.xml配置中的初始化参数 String dataSourceName=this.getInitParameter("dataSourceName"); if(dataSourceName==null||dataSourceName.trim().equals("")){ System.out.println("初始化参数dataSourceName 未获取到!"); }else{ System.out.println("初始化参数dataSourceName :"+dataSourceName); } //定时任务 Timer timer = new Timer(); TimerTask tt1=new TimerTaskOne("task111"); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date startPoint_date=null; String startPoint_Str="2013-08-16 08:37:15"; int taskPeriod=20000;//毫秒 try { startPoint_date=sdf.parse(startPoint_Str); System.out.println("开始执行任务时间点:"+startPoint_Str+",此后每隔"+taskPeriod+"毫秒执行一次任务。"); } catch (ParseException e) { e.printStackTrace(); } timer.scheduleAtFixedRate(tt1, startPoint_date, taskPeriod); } public void destroy(){ System.out.println("LsyTestServlet destroy --------------------------------"); } /** * */ private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost( req, resp); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("cache-control", "no-cache"); req.setCharacterEncoding("GBK"); resp.setContentType("text/plain; charset=GBK"); work( req, resp); } protected void work(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out = resp.getWriter(); HttpSession session = request.getSession(); System.out.println(request.getParameter("startTime")); if(request.getParameter("enforceStartTask")!=null&&!request.getParameter("enforceStartTask").trim().equals("")){ if(request.getParameter("enforceStartTask").trim().equals("1")){ TimerTask task111=new TimerTaskOne("task111"); Thread th1=new Thread(task111); th1.start(); System.out.println("收到强制启动定时任务命令,开启一次定时任务。。。"); } } out.println("success"); } }
package com.sunyard.hawaii.lsy.sql; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.TimerTask; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 一个定时任务 * 这里只是简单的查表并更新字段。 * * @author lushuaiyin * */ public class TimerTaskOne extends TimerTask{ String name; public TimerTaskOne(String name){ this.name=name; } @Override public void run() { // TODO Auto-generated method stub SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); long startTime=new Date().getTime(); System.out.println(""); System.out.println("执行一次任务:开始时间"+sdf.format(new Date())); String sql = "select id,cname,bak,flag from LSY_TEST"; Map resultData=LsySqlUtil.getInstancce().selectSql(sql); if(resultData!=null){ Iterator it=resultData.keySet().iterator(); for(;it.hasNext();){ Object key=it.next(); Object value=resultData.get(key); Pattern p=Pattern.compile("^[0-9]+$"); Matcher m=p.matcher(key.toString()); if(m.find()){ Map row=(Map)value; String id=(String)row.get("ID"); String bak=(String)row.get("BAK"); if(id!=null&&!id.trim().equals("")){ String updateSql="update LSY_TEST " + "set CDATE=date('"+sdf.format(new Date())+"') " + " where ID="+id.trim(); LsySqlUtil.getInstancce().executeSql(updateSql); System.out.println(updateSql); } }//end if }// end for }//end if long endTime=new Date().getTime(); long spend=endTime-startTime; System.out.println("任务结束时间:"+sdf.format(new Date())+",花费时间:"+String.valueOf(spend)+"毫秒。"); } }
package com.sunyard.hawaii.lsy.sql; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * 封装了jdbc底层操作,数据库使用db2 * 查询功能把jdbc结果集封装到一个map中,包括字段名和值 * * 使用了单例模式 * * @author lushuaiyin * */ public class LsySqlUtil { public static final String DB2_URL = "jdbc:db2://127.0.0.1:50000/example"; public static final String DB2_USERNAME = "db2admin"; public static final String DB2_PASSWORD = "db2admin"; public Connection con = null; public PreparedStatement stmt = null; public static LsySqlUtil lsySqlUtil=null; public static LsySqlUtil getInstancce(){ if(lsySqlUtil==null){ lsySqlUtil=new LsySqlUtil(); } return lsySqlUtil; } public Connection getConnection() { try { if (con == null || con.isClosed()) {// 数据库操作 Class.forName("com.ibm.db2.jcc.DB2Driver"); con = DriverManager.getConnection(DB2_URL, DB2_USERNAME, DB2_PASSWORD); } } catch (Exception e) { e.printStackTrace(); } return con; } public void close() { try { if (stmt != null) { stmt.close(); } if (con != null) { con.close(); } } catch (Exception e) { e.printStackTrace(); } } public Map selectSql(String sql) { Map resultData = new LinkedHashMap();// 结果集,序号key即第几条;value是一个map,存放一条数据,key是数据库字段名,值是字段值。 if(sql==null||sql.trim().equals("")){ }else{ // 数据库操作 try { stmt = getInstancce().getConnection().prepareStatement(sql); ResultSet rs = stmt.executeQuery(); System.out.println("rs.getType() :" + rs.getType() + ",rs.getFetchSize():" + rs.getFetchSize()); Map tableColumns = new HashMap(); tableColumns = getResultColumns(rs); resultData.put("tableColumns", tableColumns); int rowNum = 0; while (rs.next()) { rowNum = rs.getRow(); Map oneRowData = getRowMapFromResultRow(rs, tableColumns); resultData.put(rowNum, oneRowData); } System.out.println("获取最后结果集Map大小:" + resultData.size()); System.out.println("获取最后结果集Map内容:" + resultData.toString()); } catch (Exception e) { e.printStackTrace(); } finally { try { getInstancce().close(); } catch (Exception e) { e.printStackTrace(); } } } return resultData; } //insert delete update public int executeSql(String sql) { int res = 0; if(sql==null||sql.trim().equals("")){ }else{ // 数据库操作 try { stmt = getInstancce().getConnection().prepareStatement(sql); res= stmt.executeUpdate(); /* Returns: either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing */ } catch (Exception e) { e.printStackTrace(); } finally { try { getInstancce().close(); } catch (Exception e) { e.printStackTrace(); } } } return res; } // 获取结果集的所有字段名放入一个map中 public static Map getResultColumns(ResultSet rs) { Map tableColumns = new HashMap(); try { ResultSetMetaData rsMetaData = rs.getMetaData(); for (int i = 1; i < rsMetaData.getColumnCount() + 1; i++) { System.out.println("结果集列信息:" + rsMetaData.getColumnName(i) + "------" + "getColumnLabel :" + rsMetaData.getColumnLabel(i) + ",getColumnName :" + rsMetaData.getColumnName(i) + ",rgetColumnType :" + rsMetaData.getColumnType(i) + ",getColumnTypeName :" + rsMetaData.getColumnTypeName(i) + ",getTableName :" + rsMetaData.getTableName(i)); tableColumns.put(i, rsMetaData.getColumnName(i)); } } catch (Exception e) { e.printStackTrace(); } return tableColumns; } // 把结果集中的一条数据放到一个map中 public static Map getRowMapFromResultRow(ResultSet rs, Map tableColumns) { Map rowObj = new HashMap(); if (tableColumns == null) { } else { try { Iterator it = tableColumns.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); String value_columnName = (String) tableColumns.get(key); value_columnName = value_columnName == null ? "" : value_columnName.trim(); rowObj.put(value_columnName, rs.getString(value_columnName)); } System.out.println("一条记录:" + rowObj.toString()); } catch (Exception e) { e.printStackTrace(); } } return rowObj; } public static void main(String[] args) { // TODO Auto-generated method stub String sql = "select id,cname,bak,flag from LSY_TEST"; Map resultData=LsySqlUtil.getInstancce().selectSql(sql); } }
附上表结构:
CREATE TABLE AGENT.LSY_TEST ( ID INTEGER NOT NULL, CNAME VARCHAR(100), CDATE DATE, BAK VARCHAR(100), FLAG INTEGER ) IN USERSPACE1; ALTER TABLE AGENT.LSY_TEST DATA CAPTURE NONE PCTFREE 0 LOCKSIZE ROW APPEND OFF NOT VOLATILE; COMMENT ON AGENT.LSY_TEST ( ID IS '主键', CNAME IS '名称', BAK IS '备注', FLAG IS '标志' );
启动工程,定时任务控制台打印(其中也可以强制法命令启动任务,具体看代码):
2013-8-16 8:36:21 org.apache.coyote.http11.Http11Protocol init 信息: Initializing Coyote HTTP/1.1 on http-80 2013-8-16 8:36:21 org.apache.catalina.startup.Catalina load 信息: Initialization processed in 265 ms 2013-8-16 8:36:21 org.apache.catalina.core.StandardService start 信息: Starting service Catalina 2013-8-16 8:36:21 org.apache.catalina.core.StandardEngine start 信息: Starting Servlet Engine: Apache Tomcat/5.0.28 2013-8-16 8:36:21 org.apache.catalina.core.StandardHost start 信息: XML validation disabled 2013-8-16 8:36:21 org.apache.catalina.core.StandardHost getDeployer 信息: Create Host deployer for direct deployment ( non-jmx ) 2013-8-16 8:36:21 org.apache.catalina.core.StandardHostDeployer install 信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\admin.xml 2013-8-16 8:36:21 org.apache.struts.util.PropertyMessageResources <init> 信息: Initializing, config='org.apache.struts.util.LocalStrings', returnNull=true 2013-8-16 8:36:21 org.apache.struts.util.PropertyMessageResources <init> 信息: Initializing, config='org.apache.struts.action.ActionResources', returnNull=true 2013-8-16 8:36:21 org.apache.struts.util.PropertyMessageResources <init> 信息: Initializing, config='org.apache.webapp.admin.ApplicationResources', returnNull=true 2013-8-16 8:36:22 org.apache.catalina.core.StandardHostDeployer install 信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\balancer.xml 2013-8-16 8:36:22 org.apache.catalina.core.StandardHostDeployer install 信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\manager.xml 2013-8-16 8:36:22 org.apache.catalina.core.StandardHostDeployer install 信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\webagent.xml LsyTestServlet init -------------------------------- 初始化参数dataSourceName :data1 开始执行任务时间点:2013-08-16 08:37:15,此后每隔20000毫秒执行一次任务。 2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install 信息: Installing web application at context path /downfle from URL file:D:\appEclipse\Tomcat5.0\webapps\downfle 2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install 信息: Installing web application at context path /jsp-examples from URL file:D:\appEclipse\Tomcat5.0\webapps\jsp-examples 2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install 信息: Installing web application at context path from URL file:D:\appEclipse\Tomcat5.0\webapps\ROOT 2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install 信息: Installing web application at context path /servlets-examples from URL file:D:\appEclipse\Tomcat5.0\webapps\servlets-examples 2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install 信息: Installing web application at context path /tomcat-docs from URL file:D:\appEclipse\Tomcat5.0\webapps\tomcat-docs 2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install 信息: Installing web application at context path /webdav from URL file:D:\appEclipse\Tomcat5.0\webapps\webdav 2013-8-16 8:36:23 org.apache.coyote.http11.Http11Protocol start 信息: Starting Coyote HTTP/1.1 on http-80 2013-8-16 8:36:23 org.apache.jk.common.ChannelSocket init 信息: JK2: ajp13 listening on /0.0.0.0:8009 2013-8-16 8:36:23 org.apache.jk.server.JkMain start 信息: Jk running ID=0 time=0/63 config=D:\appEclipse\Tomcat5.0\conf\jk2.properties 2013-8-16 8:36:23 org.apache.catalina.startup.Catalina start 信息: Server startup in 1968 ms 执行一次任务:开始时间2013-08-16 08:37:15 rs.getType() :1003,rs.getFetchSize():0 结果集列信息:ID------getColumnLabel :ID,getColumnName :ID,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST 结果集列信息:CNAME------getColumnLabel :CNAME,getColumnName :CNAME,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST 结果集列信息:BAK------getColumnLabel :BAK,getColumnName :BAK,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST 结果集列信息:FLAG------getColumnLabel :FLAG,getColumnName :FLAG,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST 一条记录:{CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1} 一条记录:{CNAME=cc2, BAK=b2, ID=12, FLAG=0} 一条记录:{CNAME=cc3, BAK=b33, ID=13, FLAG=0} 一条记录:{CNAME=cc4, BAK=b4, ID=14, FLAG=1} 一条记录:{CNAME=cc5, BAK=b5, ID=15, FLAG=1} 获取最后结果集Map大小:6 获取最后结果集Map内容:{tableColumns={1=ID, 2=CNAME, 3=BAK, 4=FLAG}, 1={CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}, 2={CNAME=cc2, BAK=b2, ID=12, FLAG=0}, 3={CNAME=cc3, BAK=b33, ID=13, FLAG=0}, 4={CNAME=cc4, BAK=b4, ID=14, FLAG=1}, 5={CNAME=cc5, BAK=b5, ID=15, FLAG=1}} update LSY_TEST set CDATE=date('2013-08-16 08:37:15') where ID=11 update LSY_TEST set CDATE=date('2013-08-16 08:37:15') where ID=12 update LSY_TEST set CDATE=date('2013-08-16 08:37:15') where ID=13 update LSY_TEST set CDATE=date('2013-08-16 08:37:15') where ID=14 update LSY_TEST set CDATE=date('2013-08-16 08:37:15') where ID=15 任务结束时间:2013-08-16 08:37:15,花费时间:375毫秒。 执行一次任务:开始时间2013-08-16 08:37:35 rs.getType() :1003,rs.getFetchSize():0 结果集列信息:ID------getColumnLabel :ID,getColumnName :ID,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST 结果集列信息:CNAME------getColumnLabel :CNAME,getColumnName :CNAME,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST 结果集列信息:BAK------getColumnLabel :BAK,getColumnName :BAK,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST 结果集列信息:FLAG------getColumnLabel :FLAG,getColumnName :FLAG,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST 一条记录:{CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1} 一条记录:{CNAME=cc2, BAK=b2, ID=12, FLAG=0} 一条记录:{CNAME=cc3, BAK=b33, ID=13, FLAG=0} 一条记录:{CNAME=cc4, BAK=b4, ID=14, FLAG=1} 一条记录:{CNAME=cc5, BAK=b5, ID=15, FLAG=1} 获取最后结果集Map大小:6 获取最后结果集Map内容:{tableColumns={1=ID, 2=CNAME, 3=BAK, 4=FLAG}, 1={CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}, 2={CNAME=cc2, BAK=b2, ID=12, FLAG=0}, 3={CNAME=cc3, BAK=b33, ID=13, FLAG=0}, 4={CNAME=cc4, BAK=b4, ID=14, FLAG=1}, 5={CNAME=cc5, BAK=b5, ID=15, FLAG=1}} update LSY_TEST set CDATE=date('2013-08-16 08:37:35') where ID=11 update LSY_TEST set CDATE=date('2013-08-16 08:37:35') where ID=12 update LSY_TEST set CDATE=date('2013-08-16 08:37:35') where ID=13 update LSY_TEST set CDATE=date('2013-08-16 08:37:35') where ID=14 update LSY_TEST set CDATE=date('2013-08-16 08:37:35') where ID=15 任务结束时间:2013-08-16 08:37:35,花费时间:95毫秒。 null 收到强制启动定时任务命令,开启一次定时任务。。。 执行一次任务:开始时间2013-08-16 08:37:46 rs.getType() :1003,rs.getFetchSize():0 结果集列信息:ID------getColumnLabel :ID,getColumnName :ID,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST 结果集列信息:CNAME------getColumnLabel :CNAME,getColumnName :CNAME,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST 结果集列信息:BAK------getColumnLabel :BAK,getColumnName :BAK,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST 结果集列信息:FLAG------getColumnLabel :FLAG,getColumnName :FLAG,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST 一条记录:{CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1} 一条记录:{CNAME=cc2, BAK=b2, ID=12, FLAG=0} 一条记录:{CNAME=cc3, BAK=b33, ID=13, FLAG=0} 一条记录:{CNAME=cc4, BAK=b4, ID=14, FLAG=1} 一条记录:{CNAME=cc5, BAK=b5, ID=15, FLAG=1} 获取最后结果集Map大小:6 获取最后结果集Map内容:{tableColumns={1=ID, 2=CNAME, 3=BAK, 4=FLAG}, 1={CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}, 2={CNAME=cc2, BAK=b2, ID=12, FLAG=0}, 3={CNAME=cc3, BAK=b33, ID=13, FLAG=0}, 4={CNAME=cc4, BAK=b4, ID=14, FLAG=1}, 5={CNAME=cc5, BAK=b5, ID=15, FLAG=1}} update LSY_TEST set CDATE=date('2013-08-16 08:37:46') where ID=11 update LSY_TEST set CDATE=date('2013-08-16 08:37:46') where ID=12 update LSY_TEST set CDATE=date('2013-08-16 08:37:46') where ID=13 update LSY_TEST set CDATE=date('2013-08-16 08:37:46') where ID=14 update LSY_TEST set CDATE=date('2013-08-16 08:37:46') where ID=15 任务结束时间:2013-08-16 08:37:46,花费时间:111毫秒。