首先,需要导入quartz 的jar包 ① applicationContext.xml <!-- 轮询任务 --> <import resource="classpath:/conf/quartz/ctmanage-schedule.xml" /> ② ctmanage-schedule.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 配置该项目的定时任务 --> <!-- 生成账单-定义调用对象和调用对象的方法 --> <bean id="generateBillTaskMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="generateBillService" /> <property name="targetMethod" value="generateBill" /> <property name="concurrent" value="false" /> </bean> <!-- 生成账单-定义触发时间 --> <!-- 0 0 2 1 * ? 每个月1号凌晨2点执行 正式--> <!-- 1/15 * * * * ? 启动就执行 每隔15秒执行一次--> <!-- 0 0/3 * * * ? 每三分钟执行一次 启动服务器三分钟后执行第一次--> <bean id="generateBillTaskMethodTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="generateBillTaskMethod" /> <property name="cronExpression"> <value>0 0 2 1 * ?</value> </property> </bean> <!-- 轮询任务列表 --> <bean id="timerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="generateBillTaskMethodTrigger" /> </list> </property> <property name="quartzProperties"> <props> <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop> <prop key="org.quartz.threadPool.threadCount">10</prop> <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop> </props> </property> <property name="startupDelay" value="5"></property> </bean> </beans> ③ 配置实现类 <!-- 定时任务 配置 --> <bean id="generateBillService" class="com.bontai.ct.manager.helper.timed.GenerateBillService"> <property name="generateBillBiz" ref="generateBillBiz" /> </bean> <bean id="generateBillBiz" class="com.bontai.ct.manager.helper.timed.impl.GenerateBillBizImpl"> <property name="ctUserDAO" ref="ctUserDAO"/> <property name="ctGroupDAO" ref="ctGroupDAO"/> <property name="fmOrderDAO" ref="fmOrderDAO"/> <property name="acBillDAO" ref="acBillDAO"/> <property name="acBillOrderDAO" ref="acBillOrderDAO"/> <property name="billDAO" ref="billDAO"/> </bean> ④ 代码 //service package com.bontai.ct.manager.helper.timed; public class GenerateBillService { private GenerateBillBiz generateBillBiz; public GenerateBillBiz getGenerateBillBiz() { return generateBillBiz; } public void setGenerateBillBiz(GenerateBillBiz generateBillBiz) { this.generateBillBiz = generateBillBiz; } //定时任务-生成账单(每月1日为所有机构自动生成账单) public synchronized void generateBill(){ System.out.println("=================开始执行轮询任务=================="); this.generateBillBiz.generateBill(); } } //biz package com.bontai.ct.manager.helper.timed; public interface GenerateBillBiz { public void generateBill(); } //bizImpl package com.bontai.ct.manager.helper.timed.impl; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.transaction.annotation.Transactional; import com.bontai.ct.manager.dao.custom.mybatis.BillDAO; import com.bontai.ct.manager.dao.db.AcBillDAO; import com.bontai.ct.manager.dao.db.AcBillOrderDAO; import com.bontai.ct.manager.dao.db.CtGroupDAO; import com.bontai.ct.manager.dao.db.CtUserDAO; import com.bontai.ct.manager.dao.db.FmOrderDAO; import com.bontai.ct.manager.entity.mapping.AcBill; import com.bontai.ct.manager.entity.mapping.AcBillOrder; import com.bontai.ct.manager.entity.mapping.CtUser; import com.bontai.ct.manager.entity.mapping.FmOrder; import com.bontai.ct.manager.helper.timed.DatePoint; import com.bontai.ct.manager.helper.timed.GenerateBillBiz; public class GenerateBillBizImpl implements GenerateBillBiz{ private SimpleDateFormat timeStampFormater = new SimpleDateFormat("yyyyMMddHHmmss"); private SimpleDateFormat batchNOFormat = new SimpleDateFormat("yyyyMM"); private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy"); private SimpleDateFormat monthFormat = new SimpleDateFormat("MM"); private CtUserDAO ctUserDAO; private CtGroupDAO ctGroupDAO; private FmOrderDAO fmOrderDAO; private AcBillDAO acBillDAO; private AcBillOrderDAO acBillOrderDAO; private BillDAO billDAO; //定时任务 - 生成每月机构账单 @Transactional public void generateBill() { System.out.println("==================== 定时任务 - 生成每月机构账单 start ======================"); //定义账单时间段(上月1日到最后一日) Date startTime = DatePoint.getLastMonthBeginDate(); Date endTime = DatePoint.getLastMonthEndDate(); System.out.println("====================startTime:"+startTime+"======================"); System.out.println("====================endTime:"+endTime+"======================"); //获得年月信息 int year = Integer.parseInt(yearFormat.format(startTime)); int month = Integer.parseInt(monthFormat.format(startTime)); //账单批次号 String batchNo = batchNOFormat.format(startTime); //① 查询所有机构用户 List<CtUser> userList = new ArrayList<CtUser>(); CtUser user = new CtUser(); user.setUserType("1"); userList = this.ctUserDAO.queryCtUser(user); //根据userId循环插入 账单 和 账单订单关系 for(int i = 0;i<userList.size();i++){ Long userId = userList.get(i).getId();//机构用户id Long billId = null; //① 查询用户上月的有效订单个数、账单金额、充值金额 List<AcBill> billInfo = new ArrayList<AcBill>(); Map<String,Object> params = new HashMap<String,Object>(); params.put("userId",userId); params.put("year", year); params.put("month", month); billInfo= this.billDAO.queryOrderCountAndInOutMoneyByMonth(params); //② 开始插入数据 ac_bill 插入账单 if(billInfo.size()>0){ //获得统计值 int orderCount = billInfo.get(0).getOrderCount(); BigDecimal billMoney = billInfo.get(0).getBillMoney(); BigDecimal depositMoney = billInfo.get(0).getDepositMoney(); //插入 AcBill bill = new AcBill(); bill.setUserId(userId); bill.setInvoiceStat("0"); bill.setUserType("1"); bill.setStartTime(startTime); bill.setEndTime(endTime); bill.setBillSeq(timeStampFormater.format(new Date())+userId); bill.setBatchNo(batchNo); bill.setOrderCount(orderCount); bill.setBillMoney(billMoney); bill.setDepositMoney(depositMoney); bill.setBadDebtMoney(BigDecimal.ZERO); bill.setBadDebtId(null); bill.setCrtTime(new Date()); this.acBillDAO.insertNotNull(bill); billId = bill.getId(); } //③ 查询某机构某月的订单 List<FmOrder> orderList = new ArrayList<FmOrder>(); orderList= this.billDAO.queryBillOrderByMonth(params); //④ 插入账单-订单关系 for(int j = 0;j<orderList.size();j++){ Long orderId = orderList.get(j).getId(); AcBillOrder bo = new AcBillOrder(); bo.setOrderId(orderId); bo.setBillId(billId); this.acBillOrderDAO.insertNotNull(bo); } } System.out.println("==================== 定时任务 - 生成每月机构账单 end ======================"); } //getters and setters public CtUserDAO getCtUserDAO() { return ctUserDAO; } public CtGroupDAO getCtGroupDAO() { return ctGroupDAO; } public FmOrderDAO getFmOrderDAO() { return fmOrderDAO; } public AcBillDAO getAcBillDAO() { return acBillDAO; } public AcBillOrderDAO getAcBillOrderDAO() { return acBillOrderDAO; } public void setCtUserDAO(CtUserDAO ctUserDAO) { this.ctUserDAO = ctUserDAO; } public void setCtGroupDAO(CtGroupDAO ctGroupDAO) { this.ctGroupDAO = ctGroupDAO; } public void setFmOrderDAO(FmOrderDAO fmOrderDAO) { this.fmOrderDAO = fmOrderDAO; } public void setAcBillDAO(AcBillDAO acBillDAO) { this.acBillDAO = acBillDAO; } public void setAcBillOrderDAO(AcBillOrderDAO acBillOrderDAO) { this.acBillOrderDAO = acBillOrderDAO; } public BillDAO getBillDAO() { return billDAO; } public void setBillDAO(BillDAO billDAO) { this.billDAO = billDAO; } } //DatePoint //获得上月1号的日期 public static Date getLastMonthBeginDate(){ Calendar cal = Calendar.getInstance(); cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)-1); cal.set(Calendar.DAY_OF_MONTH,1); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); return cal.getTime(); } //获得上个月最后一天的日期 public static Date getLastMonthEndDate(){ Calendar cal = Calendar.getInstance(); cal.set(Calendar.DAY_OF_MONTH, 0); cal.set(Calendar.HOUR_OF_DAY, 23); cal.set(Calendar.MINUTE, 59); cal.set(Calendar.SECOND, 59); return cal.getTime(); } ⑤ 重要sql <!-- 查询某用户某月的完成订单数/账单金额/充值金额 --> <select id="queryOrderCountAndInOutMoneyByMonth" parameterType="java.util.Map" resultType ="com.bontai.ct.manager.entity.mapping.AcBill" > SELECT DISTINCT ifnull( ( SELECT count(*) FROM fm_order o WHERE o.buyer_user_id = #{userId} AND o.deal_stat = '09' AND YEAR(o.final_time) = #{year} AND MONTH(o.final_time) = #{month} ), '0' ) as orderCount, ifnull( ( SELECT sum(c.pay_money) FROM fm_order o LEFT JOIN fm_order_cost c ON o.id = c.order_id WHERE o.buyer_user_id = #{userId} AND o.deal_stat = '09' AND YEAR(o.final_time) = #{year} AND MONTH(o.final_time) = #{month} ), '0' ) as billMoney, ifnull( ( SELECT sum(d.deposit_money) FROM ac_deposit d WHERE d.user_id = #{userId} AND d.deposit_stat = '1' AND d.audit_stat = '2' AND YEAR(d.deposit_time) = #{year} AND MONTH(d.deposit_time) = #{month} ), '0' ) as depositMoney </select> <!-- 查询某机构某月的订单 --> <select id="queryBillOrderByMonth" parameterType="java.util.Map" resultType ="com.bontai.ct.manager.entity.mapping.FmOrder" > SELECT o.id as id FROM fm_order o WHERE o.buyer_user_id = #{userId} AND o.deal_stat = '09' AND YEAR(o.final_time) = #{year} AND MONTH(o.final_time) = #{month} </select>