SSM综合项目实战(TTSC) -- day13 订单、定时器Quartz

一、实现跳转订单结算页面

1、分析跳转到订单结算页面的url




2、用户跳转到订单页面流程分析




3、使用拦截器实现跳转到订单页面之前的登录拦截



package com.taotao.portal.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.taotao.manager.pojo.User;
import com.taotao.portal.utils.CookieUtils;
import com.taotao.sso.service.UserService;

public class OrderInterceptor implements HandlerInterceptor {

	@Value("${COOKIE_TICKET}")
	private String COOKIE_TICKET;

	@Autowired
	private UserService userService;

	/**
	 * 前置拦截,在进入Controller之前,返回值为true,表示不拦截,false表示拦截
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 从cookie中获取用户的ticket信息
		String ticket = CookieUtils.getCookieValue(request, this.COOKIE_TICKET, true);
		// 判断用户ticket是否为null
		if (StringUtils.isBlank(ticket)) {
			// 如果为null,表示用户未登录
			// 获取用户请求controller之前的url
			String redirectURL = request.getRequestURL().toString();
			// 跳转到登录页面
			response.sendRedirect("http://www.taotao.com/page/login.html?redirectURL=" + redirectURL);
			// 进行拦截,返回false
			return false;
		}
		// 如果ticket不为null,根据ticket查询用户信息
		User user = this.userService.queryUserByTicket(ticket);
		// 判断用户是否为null
		if (user == null) {
			// 表示用户登录已经超时,需要重新登录
			// 跳转到登录页面
			response.sendRedirect("http://www.taotao.com/page/login.html");
			// 进行拦截,返回false
			return false;
		}
		// 如果以上判断都没有问题,表示已经登录,将用户信息放到request中并且放行
		request.setAttribute("user", user);
		return true;
	}

	/**
	 * 后置拦截,在处理完controller中代码,返回modelandView之前进行拦截
	 */
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}

	/**
	 * 执行完controller并且已经到会modelandView之后的拦截,主要用于记录错误日志等功能
	 */
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

}

4、在springmvc.xml中配置登录拦截器




5、编写Controller代码

package com.taotao.portal.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.taotao.cart.service.CartService;
import com.taotao.manager.pojo.Cart;
import com.taotao.manager.pojo.User;
import com.taotao.portal.utils.CookieUtils;
import com.taotao.sso.service.UserService;

@Controller
@RequestMapping("order")
public class OrderController {

	@Value("${COOKIE_TICKET}")
	private String COOKIE_TICKET;

	@Autowired
	private UserService userService;

	@Autowired
	private CartService cartService;

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String create(Model model, HttpServletRequest request) {
		// 从request中获取用户信息
		User user = (User) request.getAttribute("user");
		// 用户已经登录,查询用户购物车信息
		List<Cart> cartList = this.cartService.queryCartByUserId(user.getId());
		// 把购物车信息放到Model中传递到后台页面
		model.addAttribute("carts", cartList);

		return "order-cart";
	}
}

6、改造PageController中通用页面的跳转方法




7、改造登录页面的登录js事件




8、页面测试效果



二、创建订单服务

1、导入数据库表




CREATE TABLE `tb_order` (
  `order_id` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '订单id',
  `payment` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '实付金额。精确到2位小数;单位:元。如:200.07,表示:200元7分',
  `payment_type` int(2) DEFAULT NULL COMMENT '支付类型,1、在线支付,2、货到付款',
  `post_fee` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '邮费。精确到2位小数;单位:元。如:200.07,表示:200元7分',
  `status` int(10) DEFAULT NULL COMMENT '状态:1、未付款,2、已付款,3、未发货,4、已发货,5、交易成功,6、交易关闭',
  `create_time` datetime DEFAULT NULL COMMENT '订单创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '订单更新时间',
  `payment_time` datetime DEFAULT NULL COMMENT '付款时间',
  `consign_time` datetime DEFAULT NULL COMMENT '发货时间',
  `end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
  `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
  `shipping_name` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '物流名称',
  `shipping_code` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '物流单号',
  `user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
  `buyer_message` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '买家留言',
  `buyer_nick` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '买家昵称',
  `buyer_rate` int(2) DEFAULT NULL COMMENT '买家是否已经评价',
  UNIQUE KEY `order_id` (`order_id`) USING BTREE,
  KEY `create_time` (`create_time`),
  KEY `buyer_nick` (`buyer_nick`),
  KEY `status` (`status`),
  KEY `payment_type` (`payment_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


CREATE TABLE `tb_order_item` (
  `item_id` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '商品id',
  `order_id` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '订单id',
  `num` int(10) DEFAULT NULL COMMENT '商品购买数量',
  `title` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '商品标题',
  `price` bigint(50) DEFAULT NULL COMMENT '商品单价',
  `total_fee` bigint(50) DEFAULT NULL COMMENT '商品总金额',
  `pic_path` varchar(2000) COLLATE utf8_bin DEFAULT NULL COMMENT '商品图片地址',
  KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_order_shipping
-- ----------------------------
DROP TABLE IF EXISTS `tb_order_shipping`;
CREATE TABLE `tb_order_shipping` (
  `order_id` varchar(50) NOT NULL COMMENT '订单ID',
  `receiver_name` varchar(20) DEFAULT NULL COMMENT '收货人全名',
  `receiver_phone` varchar(20) DEFAULT NULL COMMENT '固定电话',
  `receiver_mobile` varchar(30) DEFAULT NULL COMMENT '移动电话',
  `receiver_state` varchar(10) DEFAULT NULL COMMENT '省份',
  `receiver_city` varchar(10) DEFAULT NULL COMMENT '城市',
  `receiver_district` varchar(20) DEFAULT NULL COMMENT '区/县',
  `receiver_address` varchar(200) DEFAULT NULL COMMENT '收货地址,如:xx路xx号',
  `receiver_zip` varchar(6) DEFAULT NULL COMMENT '邮政编码,如:310001',
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、导入订单相关的pojo类




package com.taotao.manager.pojo;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

@Table(name = "tb_order")
public class Order implements Serializable{

    @Id
    private String orderId;

    private String payment;

    private Integer paymentType;

    private String postFee;

    private Integer status;

    private Date createTime;

    private Date updateTime;

    private Date paymentTime;

    private Date consignTime;

    private Date endTime;

    private Date closeTime;

    private String shippingName;

    private String shippingCode;

    private Long userId;

    private String buyerMessage;

    private String buyerNick;

    private Integer buyerRate;

    // 订单商品
    // @Transient和数据库表映射的时候,忽略该属性
    @Transient
    private List<OrderItem> orderItems;

    // 订单物流
    @Transient
    private OrderShipping orderShipping;

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getPayment() {
        return payment;
    }

    public void setPayment(String payment) {
        this.payment = payment;
    }

    public Integer getPaymentType() {
        return paymentType;
    }

    public void setPaymentType(Integer paymentType) {
        this.paymentType = paymentType;
    }

    public String getPostFee() {
        return postFee;
    }

    public void setPostFee(String postFee) {
        this.postFee = postFee;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Date getPaymentTime() {
        return paymentTime;
    }

    public void setPaymentTime(Date paymentTime) {
        this.paymentTime = paymentTime;
    }

    public Date getConsignTime() {
        return consignTime;
    }

    public void setConsignTime(Date consignTime) {
        this.consignTime = consignTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Date getCloseTime() {
        return closeTime;
    }

    public void setCloseTime(Date closeTime) {
        this.closeTime = closeTime;
    }

    public String getShippingName() {
        return shippingName;
    }

    public void setShippingName(String shippingName) {
        this.shippingName = shippingName;
    }

    public String getShippingCode() {
        return shippingCode;
    }

    public void setShippingCode(String shippingCode) {
        this.shippingCode = shippingCode;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getBuyerMessage() {
        return buyerMessage;
    }

    public void setBuyerMessage(String buyerMessage) {
        this.buyerMessage = buyerMessage;
    }

    public String getBuyerNick() {
        return buyerNick;
    }

    public void setBuyerNick(String buyerNick) {
        this.buyerNick = buyerNick;
    }

    public Integer getBuyerRate() {
        return buyerRate;
    }

    public void setBuyerRate(Integer buyerRate) {
        this.buyerRate = buyerRate;
    }

    public List<OrderItem> getOrderItems() {
        return orderItems;
    }

    public void setOrderItems(List<OrderItem> orderItems) {
        this.orderItems = orderItems;
    }

    public OrderShipping getOrderShipping() {
        return orderShipping;
    }

    public void setOrderShipping(OrderShipping orderShipping) {
        this.orderShipping = orderShipping;
    }

    @Override
    public String toString() {
        return "Order [orderId=" + orderId + ", payment=" + payment + ", paymentType="
                + paymentType + ", postFee=" + postFee + ", status=" + status + ", createTime="
                + createTime + ", updateTime=" + updateTime + ", paymentTime=" + paymentTime
                + ", consignTime=" + consignTime + ", endTime=" + endTime + ", closeTime="
                + closeTime + ", shippingName=" + shippingName + ", shippingCode=" + shippingCode
                + ", userId=" + userId + ", buyerMessage=" + buyerMessage + ", buyerNick="
                + buyerNick + ", buyerRate=" + buyerRate + ", orderItems=" + orderItems
                + ", orderShipping=" + orderShipping + "]";
    }

}

package com.taotao.manager.pojo;

import java.io.Serializable;

import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_order_item")
public class OrderItem implements Serializable{

    @Id
    private String itemId;

    @Id
    private String orderId;

    private Integer num;

    private String title;

    private Long price;

    private Long totalFee;

    private String picPath;

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Long getPrice() {
        return price;
    }

    public void setPrice(Long price) {
        this.price = price;
    }

    public Long getTotalFee() {
        return totalFee;
    }

    public void setTotalFee(Long totalFee) {
        this.totalFee = totalFee;
    }

    public String getPicPath() {
        return picPath;
    }

    public void setPicPath(String picPath) {
        this.picPath = picPath;
    }

}

package com.taotao.manager.pojo;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_order_shipping")
public class OrderShipping implements Serializable {

	@Id
	private String orderId;

	private String receiverName;

	private String receiverPhone;

	private String receiverMobile;

	private String receiverState;

	private String receiverCity;

	private String receiverDistrict;

	private String receiverAddress;

	private String receiverZip;

	private Date created;

	private Date updated;

	public String getOrderId() {
		return orderId;
	}

	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	public String getReceiverName() {
		return receiverName;
	}

	public void setReceiverName(String receiverName) {
		this.receiverName = receiverName;
	}

	public String getReceiverPhone() {
		return receiverPhone;
	}

	public void setReceiverPhone(String receiverPhone) {
		this.receiverPhone = receiverPhone;
	}

	public String getReceiverMobile() {
		return receiverMobile;
	}

	public void setReceiverMobile(String receiverMobile) {
		this.receiverMobile = receiverMobile;
	}

	public String getReceiverState() {
		return receiverState;
	}

	public void setReceiverState(String receiverState) {
		this.receiverState = receiverState;
	}

	public String getReceiverCity() {
		return receiverCity;
	}

	public void setReceiverCity(String receiverCity) {
		this.receiverCity = receiverCity;
	}

	public String getReceiverDistrict() {
		return receiverDistrict;
	}

	public void setReceiverDistrict(String receiverDistrict) {
		this.receiverDistrict = receiverDistrict;
	}

	public String getReceiverAddress() {
		return receiverAddress;
	}

	public void setReceiverAddress(String receiverAddress) {
		this.receiverAddress = receiverAddress;
	}

	public String getReceiverZip() {
		return receiverZip;
	}

	public void setReceiverZip(String receiverZip) {
		this.receiverZip = receiverZip;
	}

	public Date getCreated() {
		return created;
	}

	public void setCreated(Date created) {
		this.created = created;
	}

	public Date getUpdated() {
		return updated;
	}

	public void setUpdated(Date updated) {
		this.updated = updated;
	}

}

3、搭建订单服务系统的聚合父工程taotao-order






4、搭建订单系统的接口和服务taotao-order-interface、taotao-order-service








5、添加依赖关系

taotao-order-interface              依赖               taotao-manager-interface

taotao-order-service                依赖               taotao-order-interface、taotao-manager-mapper

6、添加tomcat插件




7、参考taotao-manager-service加入配置文件

(1)、加入操作redis的service层代码



(2)、加入配置文件

applicationContext-redis.xml




applicaitonContext-service.xml




8、创建订单功能相关的mapper,继承通用mapper




OrderMapper

package com.taotao.order.mapper;

import com.github.abel533.mapper.Mapper;
import com.taotao.manager.pojo.Order;

/**
 * 订单功能的mapper
 * @author Administrator
 *
 */
public interface OrderMapper extends Mapper<Order> {

}

OrderItemMapper

package com.taotao.order.mapper;

import com.github.abel533.mapper.Mapper;
import com.taotao.manager.pojo.OrderItem;

/**
 * 订单商品操作相关的mapper
 * 
 * @author Administrator
 *
 */
public interface OrderItemMapper extends Mapper<OrderItem> {

}

OrderShippingMapper

package com.taotao.order.mapper;

import com.github.abel533.mapper.Mapper;
import com.taotao.manager.pojo.OrderShipping;

/**
 * 订单物流操作相关的mapper
 * 
 * @author Administrator
 *
 */
public interface OrderShippingMapper extends Mapper<OrderShipping> {

}

9、编写Service层接口和实现类




package com.taotao.order.service;

/**
 * 订单相关操作的业务层接口
 * 
 * @author Administrator
 *
 */
public interface OrderService {

}

package com.taotao.order.service.impl;

import org.springframework.stereotype.Service;

import com.taotao.order.service.OrderService;

/**
 * 订单相关操作的业务层实现类
 * 
 * @author Administrator
 *
 */
@Service
public class OrderServiceImpl implements OrderService {

}

10、在order-service中声明服务的暴露、在portal中依赖order-interface及声明服务的调用






三、实现订单创建功能

1、分析提交订单按钮





2、编写OrderController.java中的提交订单的代码

	@Autowired
	private OrderService orderService;
	
	@RequestMapping(value="submit",method=RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> submit(HttpServletRequest request, Order order){
		//直接从request中获取用户登录数据
		User user = (User) request.getAttribute("user");
		//设置用户数据到订单中
		order.setUserId(user.getId());
		order.setBuyerNick(user.getUsername());
		
		//调用订单服务保存订单数据并且返回订单id
		String orderId = this.orderService.saveOrder(order);
		
		//声明返回值,并封装数据
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("status", 200);
		map.put("data", orderId);
		return map;
	}

3、在资源文件中配置用来生成订单号唯一数的redis中的key




4、编写保存订单的Service层接口和实现类

package com.taotao.order.service;

import com.taotao.manager.pojo.Order;

/**
 * 订单相关操作的业务层接口
 * 
 * @author Administrator
 *
 */
public interface OrderService {

	/**
	 * 保存订单的方法
	 * 
	 * @param order
	 * @return
	 */
	public String saveOrder(Order order);

}

package com.taotao.order.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.taotao.manager.pojo.Order;
import com.taotao.manager.pojo.OrderItem;
import com.taotao.manager.pojo.OrderShipping;
import com.taotao.order.mapper.OrderItemMapper;
import com.taotao.order.mapper.OrderMapper;
import com.taotao.order.mapper.OrderShippingMapper;
import com.taotao.order.redis.RedisUtils;
import com.taotao.order.service.OrderService;

/**
 * 订单相关操作的业务层实现类
 * 
 * @author Administrator
 *
 */
@Service
public class OrderServiceImpl implements OrderService {

	@Value("${TAOTAO_ORDER_KEY}")
	private String TAOTAO_ORDER_KEY;
	
	@Autowired
	private RedisUtils redisUtils;
	
	@Autowired
	private OrderMapper orderMapper;
	
	@Autowired
	private OrderItemMapper orderItemMapper;
	
	@Autowired
	private OrderShippingMapper orderShippingMapper;

	/**
	 * 保存订单
	 */
	public String saveOrder(Order order) {
		//创建订单号,订单号要求:唯一、可读性高、不能太长,因此选择使用用户id+redis生成的唯一数
		String orderId = "" + order.getUserId() + this.redisUtils.incr(this.TAOTAO_ORDER_KEY);
		
		//保存订单数据
		order.setOrderId(orderId);
		order.setCreateTime(new Date());
		order.setUpdateTime(order.getCreateTime());
		order.setStatus(1);
		this.orderMapper.insertSelective(order);
		
		//保存订单商品数据
		//获取订单商品列表
		List<OrderItem> orderItems = order.getOrderItems();
		//遍历订单商品列表,保存订单数据
		for (OrderItem orderItem : orderItems) {
			orderItem.setOrderId(orderId);
			this.orderItemMapper.insertSelective(orderItem);
		}
		
		//保存订单物流数据
		OrderShipping orderShipping = order.getOrderShipping();
		orderShipping.setOrderId(orderId);
		this.orderShippingMapper.insertSelective(orderShipping);
		
		return orderId;
	}

}

5、实现跳转到订单成功页面

(1)、Controller层代码

	/**
	 * 跳转到订单成功页面
	 * 
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "success", method = RequestMethod.GET)
	public String success(Model model, String id) {
		// 根据id查询订单
		Order order = this.orderService.queryOrderById(id);
		// 把查询到的订单放到Modle中,传递给页面
		model.addAttribute("order", order);
		// 把送达时间封装到Model中,传递给页面,送达时间是当前时间的两天后
		// 使用joda-time-2.5.jar插件进行时间退后设置
		model.addAttribute("date", new DateTime().plusDays(2).toString("yyyy年MM月dd日 HH:mm:ss:SSS"));

		return "success";
	}

(2)、Service层接口和实现类

	/**
	 * 根据订单id查询订单
	 * 
	 * @param id
	 * @return
	 */
	public Order queryOrderById(String id);

	/**
	 * 根据订单id查询订单
	 */
	public Order queryOrderById(String orderId) {
		// 查询订单数据
		Order order = orderMapper.selectByPrimaryKey(orderId);
		//查询订单商品
		//声明查询条件
		OrderItem param = new OrderItem();
		param.setOrderId(orderId);
		
		List<OrderItem> orderList = this.orderItemMapper.select(param);
		
		//查询订单物流
		OrderShipping orderShipping = this.orderShippingMapper.selectByPrimaryKey(orderId);
		
		//把订单商品和订单物流设置到订单中
		order.setOrderItems(orderList);
		order.setOrderShipping(orderShipping);
		//返回order对象
		return order;
	}

(3)、页面测试结果




四、Quartz定时任务介绍

1、核心接口






2、tigger触发器






3、表达式






表达式生成器:






五、Quartz定时任务使用案例

1、创建maven工程,打包方式为jar,继承taotao-parent


2、编写代码

MyJob.java

package cn.itcast.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * 
 * 
 */
public class MyJob extends QuartzJobBean {
    
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("myJob 执行了............." + context.getTrigger().getKey().getName());
        ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().getJobDataMap()
                .get("applicationContext");
        System.out.println("获取到的Spring容器是: " + applicationContext);
        
    }

}

Main.java

package cn.itcast.quartz;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
	
	public static void main(String[] args) {
		new ClassPathXmlApplicationContext("classpath:applicationContext-scheduler.xml");
	}

}

HelloJob.java

/* 
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 *   
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations 
 * under the License.
 * 
 */
 
package cn.itcast.quartz.example;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * <p>
 * This is just a simple job that says "Hello" to the world.
 * </p>
 * 
 * @author Bill Kratzer
 */
public class HelloJob implements Job {

    private static Logger _log = LoggerFactory.getLogger(HelloJob.class);

    /**
     * <p>
     * Empty constructor for job initilization
     * </p>
     * <p>
     * Quartz requires a public empty constructor so that the
     * scheduler can instantiate the class whenever it needs.
     * </p>
     */
    public HelloJob() {
    }

    /**
     * <p>
     * Called by the <code>{@link org.quartz.Scheduler}</code> when a
     * <code>{@link org.quartz.Trigger}</code> fires that is associated with
     * the <code>Job</code>.
     * </p>
     * 
     * @throws JobExecutionException
     *             if there is an exception while executing the job.
     */
    public void execute(JobExecutionContext context)
        throws JobExecutionException {

        // Say Hello to the World and display the date/time
        _log.info("Hello World! - " + new Date());
    }

}

SimpleCronExample.java

/* 
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 *   
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations 
 * under the License.
 * 
 */

package cn.itcast.quartz.example;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.DateBuilder.evenMinuteDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * This Example will demonstrate how to start and shutdown the Quartz scheduler and how to schedule
 * a job to run in Quartz.
 * 
 * @author Bill Kratzer
 */
public class SimpleCronExample {

    public void run() throws Exception {
        Logger log = LoggerFactory.getLogger(SimpleCronExample.class);

        log.info("------- Initializing ----------------------");

        // 定义调度器
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();

        log.info("------- Initialization Complete -----------");

        // 获取当前时间的下一分钟
        Date runTime = evenMinuteDate(new Date());

        log.info("------- Scheduling Job  -------------------");

        // 定义job
        JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build();

        // 定义触发器,每2秒执行一次
        Trigger trigger = newTrigger().withIdentity("trigger1", "group1")
                .withSchedule(cronSchedule("0 0/1 * * * ?")).build();

        // 将job注册到调度器
        sched.scheduleJob(job, trigger);
        log.info(job.getKey() + " will run at: " + runTime);

        // 启动调度器
        sched.start();

        log.info("------- Started Scheduler -----------------");

        // 等待1分钟
        log.info("------- Waiting 60 seconds... -------------");
        try {
            Thread.sleep(60L * 1000L);
        } catch (Exception e) {
            //
        }

        // 关闭调度器
        log.info("------- Shutting Down ---------------------");
        sched.shutdown(true);
        log.info("------- Shutdown Complete -----------------");
    }

    public static void main(String[] args) throws Exception {

        SimpleCronExample example = new SimpleCronExample();
        example.run();

    }

}

SimpleExample.java

/* 
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 *   
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations 
 * under the License.
 * 
 */

package cn.itcast.quartz.example;

import static org.quartz.DateBuilder.evenMinuteDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * This Example will demonstrate how to start and shutdown the Quartz scheduler and how to schedule
 * a job to run in Quartz.
 * 
 * @author Bill Kratzer
 */
public class SimpleExample {

    public void run() throws Exception {
        Logger log = LoggerFactory.getLogger(SimpleExample.class);

        log.info("------- Initializing ----------------------");

        // 定义调度器
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();

        log.info("------- Initialization Complete -----------");

        // 获取当前时间的下一分钟
        Date runTime = evenMinuteDate(new Date());

        log.info("------- Scheduling Job  -------------------");

        // 定义job
        // 在quartz中,有组的概念,组+job名称 唯一的
        JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build();

        // 定义触发器,在下一分钟启动
        Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build();

        // 将job注册到调度器
        sched.scheduleJob(job, trigger);
        log.info(job.getKey() + " will run at: " + runTime);

        // 启动调度器
        sched.start();

        log.info("------- Started Scheduler -----------------");

        // 等待65秒
        log.info("------- Waiting 65 seconds... -------------");
        try {
            // wait 65 seconds to show job
            Thread.sleep(65L * 1000L);
            // executing...
        } catch (Exception e) {
            //
        }

        // 关闭调度器
        log.info("------- Shutting Down ---------------------");
        sched.shutdown(true);
        log.info("------- Shutdown Complete -----------------");
    }

    public static void main(String[] args) throws Exception {

        SimpleExample example = new SimpleExample();
        example.run();

    }

}

3、加入配置文件

applicationContext-scheduler.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/util 
	http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 定义任务bean -->
	<bean name="myJobDetail"
		class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<!-- 指定具体的job类 -->
		<property name="jobClass" value="cn.itcast.quartz.MyJob" />
		<!-- 指定job的名称 -->
		<property name="name" value="myJob" />
		<!-- 指定job的分组 -->
		<property name="group" value="jobs" />
		<!-- 必须设置为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="myJobDetail" />
		<!-- 每一分钟执行一次 -->
		<property name="cronExpression" value="0/5 * * * * ?" />
	</bean>

	<!-- 定义触发器 -->
	<!-- 演示:一个job可以有多个trigger; -->
	<!-- <bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> 
		<property name="jobDetail" ref="myJobDetail" /> 每一分钟执行一次 <property name="cronExpression" 
		value="0 */1 * * * ?" /> </bean> -->

	<!-- 定义调度器 -->
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="cronTrigger" />
				<!-- <ref bean="cronTrigger2" /> -->
			</list>
		</property>
	</bean>

</beans>

六、实现定时删除无效订单

1、在taotao-order-service中加入定时器的配置文件


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/util 
	http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 定义任务bean -->
	<bean name="myJobDetail"
		class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<!-- 指定具体的job类 -->
		<property name="jobClass" value="com.taotao.order.quartz.OrderJob" />
		<!-- 指定job的名称 -->
		<property name="name" value="myJob" />
		<!-- 指定job的分组 -->
		<property name="group" value="jobs" />
		<!-- 必须设置为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="myJobDetail" />
		<!-- 每一分钟执行一次 -->
		<property name="cronExpression" value="0/5 * * * * ?" />
	</bean>

	<!-- 定义调度器 -->
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="cronTrigger" />
				<!-- 此处可以配置多个触发器 -->
				<!-- <ref bean="cronTrigger2" /> -->
			</list>
		</property>
	</bean>

</beans>

2、创建定时任务类


package com.taotao.order.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.taotao.order.service.OrderService;

/**
 * 定时清理无效订单的任务类
 * 
 * @author Administrator
 *
 */
public class OrderJob extends QuartzJobBean {

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		ApplicationContext app = (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
		// 使用spring容器获取订单服务,执行清理订单的方法
		app.getBean(OrderService.class).cleanOrder();
	}

}

3、编写OrderService中清理无效订单的接口和实现类

	/**
	 * 定时器中清理订单的方法
	 */
	public void cleanOrder();

	/**
	 * 清理无效订单的方法
	 */
	public void cleanOrder() {
		// 无效订单:创建订单两天之内没有付款,付款类型为在线支付的订单就是无效订单,需要关闭
		Example example = new Example(Order.class);
		Criteria criteria = example.createCriteria();

		// 设置更新条件:付款类型:在线支付(payment_type:1),
		criteria.andEqualTo("paymentType", 1);
		// 订单状态:未支付(status:1)
		criteria.andEqualTo("status", 1);
		// 订单创建时间:两天或两天前(create_time)
		criteria.andLessThanOrEqualTo("createTime", new DateTime().minusDays(2).toDate());

		Order order = new Order();
		// 把订单状态修改为关闭(status:6),
		order.setStatus(6);
		// 设置关闭时间:当前时间(close_time)
		order.setCloseTime(new Date());

		// 第一个参数:要把数据更新成什么样,第二个参数:要更新的数据的条件
		this.orderMapper.updateByExampleSelective(order, example);
	}

4、定时器启动项目即可运行,启动项目,控制台查看效果






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值