pom.xml文件内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.enjoyshop.parent</groupId>
<artifactId>enjoyshop-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.enjoyshop.order</groupId>
<artifactId>enjoyshop-order</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- <dependency> <groupId>com.enjoyshop.common</groupId> <artifactId>enjoyshop-util</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.2.Final</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- RabbitMQ -->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8084</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
这里不做详述,可参考具体源码。
订单基本信息表
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 COMMENT='订单基本信息表'
订单商品表
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(600) COLLATE utf8_bin DEFAULT NULL COMMENT '商品图片地址', KEY `order_id` (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='订单商品表'
订单用户基本信息表
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 COMMENT='订单用户基本信息表'
这里采用Hibernate校验框架进行校验
package com.enjoyshop.store.order.pojo;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Min;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers.DateDeserializer;
public class Order {
private String orderId;//id,rowKye:id+时间戳
@NotBlank
private String payment;//实付金额
private Integer paymentType; //支付类型,1、在线支付,2、货到付款
private String postFee;//邮费
/** * 初始阶段:1、未付款、未发货;初始化所有数据 * 付款阶段:2、已付款;更改付款时间 * 发货阶段:3、已发货;更改发货时间、更新时间、物流名称、物流单号 * 成功阶段:4、已成功;更改更新时间,交易结束时间,买家留言,是否已评价 * 关闭阶段:5、关闭; 更改更新时间,交易关闭时间。 * */
private Integer status;//状态:1、未付款,2、已付款,3、未发货,4、已发货,5、交易成功,6、交易关闭
@JsonDeserialize(using = DateDeserializer.class)
private Date createTime;//创建时间
@JsonDeserialize(using = DateDeserializer.class)
private Date updateTime;//更新时间
@JsonDeserialize(using = DateDeserializer.class)
private Date paymentTime;//付款时间
@JsonDeserialize(using = DateDeserializer.class)
private Date consignTime;//发货时间
@JsonDeserialize(using = DateDeserializer.class)
private Date endTime;//交易结束时间
@JsonDeserialize(using = DateDeserializer.class)
private Date closeTime;//交易关闭时间
private String shippingName;//物流名称
private String shippingCode;//物流单号
@Min(value = 1L)
private Long userId;//用户id
private String buyerMessage;//买家留言
@NotBlank
private String buyerNick;//买家昵称
private Integer buyerRate;//买家是否已经评价
@NotEmpty
private List<OrderItem> orderItems;//商品详情
private OrderShipping orderShipping; //物流地址信息
public Integer getPaymentType() {
return paymentType;
}
public void setPaymentType(Integer paymentType) {
this.paymentType = paymentType;
}
public OrderShipping getOrderShipping() {
return orderShipping;
}
public void setOrderShipping(OrderShipping orderShipping) {
this.orderShipping = orderShipping;
}
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 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 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 List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
}
package com.enjoyshop.store.order.mapper;
import org.apache.ibatis.annotations.Param;
import com.enjoyshop.store.order.bean.Where;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
public interface IMapper<T> {
/** * 按照分页查询 * * @param bounds * @return */
public PageList<T> queryList(PageBounds bounds);
/** * 按照where条件分页查询 * * @param bounds * @param where * @return */
public PageList<T> queryListByWhere(PageBounds bounds, @Param("where")Where where);
/** * 通过ID查询数据 * * @param id * @return */
public T queryByID(@Param("id") String id);
/** * 通过where条件查询 * * @param where * @return */
public T queryByWhere(@Param("where") Where where);
/** * 新增数据 * * @param t */
public void save(T t);
/** * 更新数据 * * @param t */
public void update(T t);
/** * 通过ID删除数据 * * @param id * @return 返回受影响的条数 */
public Integer deleteByID(@Param("id") Long id);
/** * 通过IDs删除数据 * * @param ids * @return 返回受影响的条数 */
public Integer deleteByIDS(@Param("ids") Long[] ids);
}
package com.enjoyshop.store.order.mapper;
import java.util.Date;
import org.apache.ibatis.annotations.Param;
import com.enjoyshop.store.order.pojo.Order;
public interface OrderMapper extends IMapper<Order>{
public void paymentOrderScan(@Param("date") Date date);
}
<?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.enjoyshop.store.order.mapper.OrderMapper">
<sql id="tableName">tb_order</sql>
<resultMap type="Order" id="pojoResultMap" autoMapping="true">
<id column="order_id" property="orderId"/>
<association property="orderShipping" javaType="OrderShipping" column="order_id" select="queryOrderShippingByOrderId" autoMapping="true"></association>
<collection property="orderItems" javaType="Arraylist" ofType="OrderItem" autoMapping="true" select="queryOrderItemByOrderId" column="order_id">
</collection>
</resultMap>
<select id="queryOrderItemByOrderId" resultType="OrderItem" parameterType="String">
SELECT * FROM tb_order_item WHERE order_id = #{orderId};
</select>
<select id="queryOrderShippingByOrderId" resultType="OrderShipping" parameterType="String">
SELECT * FROM tb_order_shipping WHERE order_id = #{orderId};
</select>
<select id="queryList" resultMap="pojoResultMap">
SELECT
*
FROM
<include refid="tableName"/>
</select>
<select id="queryByID" resultMap="pojoResultMap">
SELECT
*
FROM
<include refid="tableName"/>
WHERE order_id = #{id};
</select>
<select id="queryByWhere" parameterType="Where" resultMap="pojoResultMap">
SELECT
*
FROM
<include refid="tableName"/>
WHERE ${where.column} ${where.operater} #{where.value} LIMIT 1;
</select>
<select id="queryListByWhere" parameterType="Where" resultMap="pojoResultMap">
SELECT
*
FROM
<include refid="tableName"/>
WHERE ${where.column} ${where.operater} #{where.value};
</select>
<insert id="save">
INSERT INTO <include refid="tableName"/> VALUES (#{orderId},#{payment},#{paymentType},#{postFee},#{status},#{createTime},#{updateTime},#{paymentTime},#{consignTime},#{endTime},#{closeTime},#{shippingName},#{shippingCode},#{userId},#{buyerMessage},#{buyerNick},#{buyerRate});
INSERT INTO tb_order_item VALUES
<foreach collection="orderItems" item="item" separator=",">
(#{item.itemId},#{orderId},#{item.num},#{item.title},#{item.price},#{item.totalFee},#{item.picPath})
</foreach>
;
INSERT INTO tb_order_shipping VALUES (#{orderId},#{orderShipping.receiverName},#{orderShipping.receiverPhone},#{orderShipping.receiverMobile},#{orderShipping.receiverState},#{orderShipping.receiverCity},#{orderShipping.receiverDistrict},#{orderShipping.receiverAddress},#{orderShipping.receiverZip},NOW(),NOW());
</insert>
<update id="update">
UPDATE <include refid="tableName"/>
<set>
<if test="payment !=null and payment != ''">
payment = #{payment},
</if>
<if test="postFee !=null and postFee != ''">
post_fee = #{postFee},
</if>
<if test="status !=null and status != ''">
status = #{status},
</if>
<if test="updateTime !=null and updateTime != ''">
update_time = #{updateTime},
</if>
<if test="paymentTime !=null and paymentTime != ''">
payment_time = #{paymentTime},
</if>
<if test="consignTime !=null and consignTime != ''">
consign_time = #{consignTime},
</if>
<if test="endTime !=null and endTime != ''">
end_time = #{endTime},
</if>
<if test="closeTime !=null and closeTime != ''">
close_time = #{closeTime},
</if>
<if test="shippingName !=null and shippingName != ''">
shipping_name = #{shippingName},
</if>
<if test="shippingCode !=null and shippingCode != ''">
shipping_code = #{shippingCode},
</if>
<if test="buyerMessage !=null and buyerMessage != ''">
buyer_message = #{buyerMessage},
</if>
<if test="buyerRate !=null and buyerRate != ''">
buyer_rate = #{buyerRate},
</if>
</set>
WHERE order_id = #{orderId};
</update>
<delete id="deleteByID" parameterType="Long">
DELETE FROM <include refid="tableName"/> WHERE order_id = #{orderId};
DELETE FROM tb_order_item WHERE order_id = #{orderId};
</delete>
<delete id="deleteByIDS" parameterType="list">
DELETE FROM <include refid="tableName"/> WHERE order_id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>;
DELETE FROM tb_order_item WHERE order_id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>;
</delete>
<update id="paymentOrderScan" parameterType="Date">
UPDATE tb_order SET
status = 6,
update_time = NOW(),
close_time = NOW(),
end_time = NOW()
WHERE status = 1 AND payment_type = 1 AND create_time <= #{date}
</update>
</mapper>
需要注意的是:默认情况下,一个statement执行多条SQL语句是不支持的。需要在jdbc的连接字符串中设置,如下:
jdbc.url=jdbc:mysql://127.0.0.1:3306/enjoyshop?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
假如项目使用UFT-8编码,mysql使用GBK编码,那么使用如下两个设置useUnicode=true&characterEncoding=UTF-8 ,作用有如下两个方面:
存数据时:数据库在存放项目数据的时候会先用UTF-8格式将数据解码成字节码,然后再将解码后的字节码重新使用GBK编码存放到数据库中。
取数据时:在从数据库中取数据的时候,数据库会先将数据库中的数据按GBK格式解码成字节码,然后再将解码后的字节码重新按UTF-8格式编码数据,最后再将数据返回给客户端。
autoReconnect=true的作用是当数据库连接异常中断时,是否自动重新连接?默认为false。
allowMultiQueries=true的作用是设置允许批量操作,这样可以在 Mapper 中执行多条SQL语句。而且一个statement执行多条SQL语句时是在同一个事务中执行的。
抽取接口可以使得程序具有扩展性,实现Dao可以提供多种策略和方法。
/** * 创建订单 * * @param order */
public void createOrder(Order order);
public class OrderDAO implements IOrder{
@Autowired
private OrderMapper orderMapper;
@Override
public void createOrder(Order order) {
this.orderMapper.save(order);
}
}
public EnjoyshopResult createOrder(String json) {
Order order = null;
try {
order = objectMapper.readValue(json, Order.class);
// 校验Order对象
ValidateUtil.validate(order);
} catch (Exception e) {
return EnjoyshopResult.build(400, "请求参数有误!");
}
try {
// 生成订单ID,规则为:userid+当前时间戳
String orderId = order.getUserId() + "" + System.currentTimeMillis();
order.setOrderId(orderId);
// 设置订单的初始状态为未付款
order.setStatus(1);
// 设置订单的创建时间
order.setCreateTime(new Date());
order.setUpdateTime(order.getCreateTime());
// 设置买家评价状态,初始为未评价
order.setBuyerRate(0);
// 持久化order对象
orderDao.createOrder(order);
//发送消息到RabbitMQ
// Map<String, Object> msg = new HashMap<String, Object>(3);
// msg.put("userId", order.getUserId());
// msg.put("orderId", order.getOrderId());
// List<Long> itemIds = new ArrayList<Long>(order.getOrderItems().size());
// for (OrderItem orderItem : order.getOrderItems()) {
// itemIds.add(orderItem.getItemId());
// }
// msg.put("itemIds", itemIds);
// this.rabbitTemplate.convertAndSend(objectMapper.writeValueAsString(msg));
return EnjoyshopResult.ok(orderId);
} catch (Exception e) {
e.printStackTrace();
}
return EnjoyshopResult.build(400, "保存订单失败!");
}
这里设计了一个自定义的返回值格式EnjoyshopResult
package com.enjoyshop.store.order.bean;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
/** * 乐购商城自定义响应结构 */
public class EnjoyshopResult {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态
private Integer status;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
public static EnjoyshopResult build(Integer status, String msg, Object data) {
return new EnjoyshopResult(status, msg, data);
}
public static EnjoyshopResult ok(Object data) {
return new EnjoyshopResult(data);
}
public static EnjoyshopResult ok() {
return new EnjoyshopResult(null);
}
public EnjoyshopResult() {
}
public static EnjoyshopResult build(Integer status, String msg) {
return new EnjoyshopResult(status, msg, null);
}
public EnjoyshopResult(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public EnjoyshopResult(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
}
public Boolean isOK() {
return this.status == 200;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/** * 将json结果集转化为EnjoyshopResult对象 * * @param jsonData json数据 * @param clazz EnjoyshopResult中的object类型 * @return */
public static EnjoyshopResult formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, EnjoyshopResult.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/** * 没有object对象的转化 * * @param json * @return */
public static EnjoyshopResult format(String json) {
try {
return MAPPER.readValue(json, EnjoyshopResult.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/** * Object是集合转化 * * @param jsonData json数据 * @param clazz 集合中的类型 * @return */
public static EnjoyshopResult formatToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
}
@Autowired
private OrderService orderService;
/** * 创建订单 * @param json * @return */
@ResponseBody
@RequestMapping(value = "/create" , method = RequestMethod.POST)
public EnjoyshopResult createOrder(@RequestBody String json) {
return orderService.createOrder(json);
}
注意这里的两个重要注解:
@ResponseBody表示返回参数的数据类型是json数据。
@RequestBody表示接受参数的数据类型是json数据。
/** * 通过ID查询数据 * * @param id * @return */
public T queryByID(@Param("id") String id);
对应的mapper.xml内容
<select id="queryByID" resultMap="pojoResultMap">
SELECT
*
FROM
<include refid="tableName"/>
WHERE order_id = #{id};
</select>
@Override
public Order queryOrderById(String orderId) {
return this.orderMapper.queryByID(orderId);
}
public Order queryOrderById(String orderId) {
Order order = orderDao.queryOrderById(orderId);
return order;
}
/** * 根据订单ID查询订单 * @param orderId * @return */
@ResponseBody
@RequestMapping(value = "/query/{orderId}" ,method = RequestMethod.GET)
public Order queryOrderById(@PathVariable("orderId") String orderId) {
return orderService.queryOrderById(orderId);
}
/** * 按照where条件分页查询 * * @param bounds * @param where * @return */
public PageList<T> queryListByWhere(PageBounds bounds, @Param("where")Where where);
对应的xml内容
<select id="queryListByWhere" parameterType="Where" resultMap="pojoResultMap">
SELECT
*
FROM
<include refid="tableName"/>
WHERE ${where.column} ${where.operater} #{where.value};
</select>
@Override
public PageResult<Order> queryOrderByUserNameAndPage(String buyerNick, Integer page, Integer count) {
PageBounds bounds = new PageBounds();
bounds.setContainsTotalCount(true);
bounds.setLimit(count);
bounds.setPage(page);
bounds.setOrders(com.github.miemiedev.mybatis.paginator.domain.Order.formString("create_time.desc"));
PageList<Order> list = this.orderMapper.queryListByWhere(bounds, Where.build("buyer_nick", buyerNick));
return new PageResult<Order>(list.getPaginator().getTotalCount(), list);
}
public PageResult<Order> queryOrderByUserNameAndPage(String buyerNick, int page, int count) {
return orderDao.queryOrderByUserNameAndPage(buyerNick, page, count);
}
/** * 根据用户名分页查询订单 * @param buyerNick * @param page * @param count * @return */
@ResponseBody
@RequestMapping("/query/{buyerNick}/{page}/{count}")
public PageResult<Order> queryOrderByUserNameAndPage(@PathVariable("buyerNick") String buyerNick,@PathVariable("page") Integer page,@PathVariable("count") Integer count) {
return orderService.queryOrderByUserNameAndPage(buyerNick, page, count);
}
/** * 更新数据 * * @param t */
public void update(T t);
对应的xml内容如下:
<update id="update">
UPDATE <include refid="tableName"/>
<set>
<if test="payment !=null and payment != ''">
payment = #{payment},
</if>
<if test="postFee !=null and postFee != ''">
post_fee = #{postFee},
</if>
<if test="status !=null and status != ''">
status = #{status},
</if>
<if test="updateTime !=null and updateTime != ''">
update_time = #{updateTime},
</if>
<if test="paymentTime !=null and paymentTime != ''">
payment_time = #{paymentTime},
</if>
<if test="consignTime !=null and consignTime != ''">
consign_time = #{consignTime},
</if>
<if test="endTime !=null and endTime != ''">
end_time = #{endTime},
</if>
<if test="closeTime !=null and closeTime != ''">
close_time = #{closeTime},
</if>
<if test="shippingName !=null and shippingName != ''">
shipping_name = #{shippingName},
</if>
<if test="shippingCode !=null and shippingCode != ''">
shipping_code = #{shippingCode},
</if>
<if test="buyerMessage !=null and buyerMessage != ''">
buyer_message = #{buyerMessage},
</if>
<if test="buyerRate !=null and buyerRate != ''">
buyer_rate = #{buyerRate},
</if>
</set>
WHERE order_id = #{orderId};
</update>
@Override
public ResultMsg changeOrderStatus(Order order) {
try {
order.setUpdateTime(new Date());
this.orderMapper.update(order);
} catch (Exception e) {
e.printStackTrace();
return new ResultMsg("500", "更新订单出错!");
}
return new ResultMsg("200", "更新成功!");
}
public ResultMsg changeOrderStatus(String json) {
Order order = null;
try {
order = objectMapper.readValue(json, Order.class);
} catch (Exception e) {
e.printStackTrace();
return new ResultMsg("400", "请求参数有误!");
}
return this.orderDao.changeOrderStatus(order);
}
/** * 修改订单状态 * @param json * @return */
@ResponseBody
@RequestMapping(value="/changeOrderStatus",method = RequestMethod.POST)
public ResultMsg changeOrderStatus(@RequestBody String json) {
return orderService.changeOrderStatus(json);
}
页面通过ModelAndView对象来封装数据到前端页面来展示。
@RequestMapping(value = "{itemId}", method = RequestMethod.GET)
public ModelAndView toOrder(@PathVariable("itemId") Long itemId) {
ModelAndView mv = new ModelAndView("order");
Item item = this.itemService.queryItemById(itemId);
mv.addObject("item", item);
return mv;
}
关于SpringMVC拦截器的使用请参考这里。点我
在使用拦截器先解决一个问题:
当我们使用拦截器后,通过token查询用户信息会进行了2次。一次是在拦截器中查询,一次是在Controller查询,存在性能和资源浪费问题。那么如何将拦截器中的数据传递到Controller?答案是使用ThreadLocal实现,因为进入tomcat和产生响应前,都处于同一个线程中。
定义ThreadLocal
package com.enjoyshop.web.threadlocal;
import com.enjoyshop.web.bean.User;
public class UserThreadLocal {
private static final ThreadLocal<User> LOCAL = new ThreadLocal<User>();
public static void set(User user) {
LOCAL.set(user);
}
public static User get() {
return LOCAL.get();
}
}
这样我们只需要在拦截器中将User对象放置到ThreadLocal中就可以了。
package com.enjoyshop.web.handlerInterceptor;
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.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.enjoyshop.common.utils.CookieUtils;
import com.enjoyshop.web.bean.User;
import com.enjoyshop.web.service.PropertieService;
import com.enjoyshop.web.service.UserService;
import com.enjoyshop.web.threadlocal.UserThreadLocal;
public class UserLoginHandlerInterceptor implements HandlerInterceptor {
public static final String COOKIE_NAME = "TT_TOKEN";
@Autowired
private PropertieService propertieService;
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
UserThreadLocal.set(null);//清空当前线程中的User对象
String loginUrl = propertieService.ENJOYSHOP_SSO_URL + "/user/login.html";
String token = CookieUtils.getCookieValue(request, COOKIE_NAME);
if (StringUtils.isEmpty(token)) {
// 未登录状态
response.sendRedirect(loginUrl);
return false;
}
User user = this.userService.queryUserByToken(token);
if (null == user) {
// 未登录状态
response.sendRedirect(loginUrl);
return false;
}
//处于登录状态
UserThreadLocal.set(user); //将User对象放置到ThreadLocal中
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/order/**"/>
<bean class="com.enjoyshop.web.handlerInterceptor.UserLoginHandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
@RequestMapping(value = "submit", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> submitOrder(Order order) {
Map<String, Object> result = new HashMap<String, Object>();
String orderId = this.orderService.submitOrder(order);
if (StringUtils.isEmpty(orderId)) {
result.put("status", 300);
} else {
result.put("status", 200);
result.put("data", orderId);
}
return result;
}
public String submitOrder(Order order) {
User user = UserThreadLocal.get(); // 从本地线程中获取User对象
order.setUserId(user.getId());
order.setBuyerNick(user.getUsername());
try {
String url = ENJOYSHOP_ORDER_URL + "/order/create";
HttpResult httpResult = this.apiService.doPostJson(url, MAPPER.writeValueAsString(order));
if (httpResult.getCode().intValue() == 200) {
String jsonData = httpResult.getData();
JsonNode jsonNode = MAPPER.readTree(jsonData);
if (jsonNode.get("status").intValue() == 200) {
// 订单提交成功,返回订单号
return jsonNode.get("data").asText();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public HttpResult doPostJson(String url, String json) throws IOException {
// 创建http POST请求
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
if (null != json) {
// 构造一个字符串式的实体
StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
// 将请求实体设置到httpPost对象中
httpPost.setEntity(stringEntity);
}
CloseableHttpResponse response = null;
try {
// 执行请求
response = getHttpClient().execute(httpPost);
return new HttpResult(response.getStatusLine().getStatusCode(),
EntityUtils.toString(response.getEntity(), "UTF-8"));
} finally {
if (response != null) {
response.close();
}
}
}
controller层
@RequestMapping("success")
public ModelAndView success(@RequestParam("id") String orderId) {
ModelAndView mv = new ModelAndView("success");
Order order = this.orderService.queryOrderById(orderId);
mv.addObject("order", order);
// 当前时间推后2天,格式化:xx月xx日
mv.addObject("date", new DateTime().plusDays(2).toString("MM月dd日"));
return mv;
}
service层
public Order queryOrderById(String orderId) {
String url = ENJOYSHOP_ORDER_URL + "/order/query/" + orderId;
try {
String jsonData = this.apiService.doGet(url);
if (StringUtils.isNotEmpty(jsonData)) {
return MAPPER.readValue(jsonData, Order.class);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}