SpringBoot电脑商城项目--创建订单+统计业务方法耗时

创建订单

1. 创建数据库表

一共有两个表,一个是订单表,一个是订单商品表,两张表差不太多,order表是记录有这么一个订单,orderItem表可以用于订单列表的展示

sql 复制代码
CREATE TABLE t_order (
	oid INT AUTO_INCREMENT COMMENT '订单id',
	uid INT NOT NULL COMMENT '用户id',
	recv_name VARCHAR(20) NOT NULL COMMENT '收货人姓名',
	recv_phone VARCHAR(20) COMMENT '收货人电话',
	recv_province VARCHAR(15) COMMENT '收货人所在省',
	recv_city VARCHAR(15) COMMENT '收货人所在市',
	recv_area VARCHAR(15) COMMENT '收货人所在区',
	recv_address VARCHAR(50) COMMENT '收货详细地址',
	total_price BIGINT COMMENT '总价',
	status INT COMMENT '状态:0-未支付,1-已支付,2-已取消,3-已关闭,4-已完成',
	order_time DATETIME COMMENT '下单时间',
	pay_time DATETIME COMMENT '支付时间',
	created_user VARCHAR(20) COMMENT '创建人',
	created_time DATETIME COMMENT '创建时间',
	modified_user VARCHAR(20) COMMENT '修改人',
	modified_time DATETIME COMMENT '修改时间',
	PRIMARY KEY (oid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE t_order_item (
	id INT AUTO_INCREMENT COMMENT '订单中的商品记录的id',
	oid INT NOT NULL COMMENT '所归属的订单的id',
	pid INT NOT NULL COMMENT '商品的id',
	title VARCHAR(100) NOT NULL COMMENT '商品标题',
	image VARCHAR(500) COMMENT '商品图片',
	price BIGINT COMMENT '商品价格',
	num INT COMMENT '购买数量',
	created_user VARCHAR(20) COMMENT '创建人',
	created_time DATETIME COMMENT '创建时间',
	modified_user VARCHAR(20) COMMENT '修改人',
	modified_time DATETIME COMMENT '修改时间',
	PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. 创建对应的实体类

  • 订单Order实体类
java 复制代码
package com.cy.store.entity;

import lombok.Data;

import java.util.Date;

/** 订单数据的实体类 */
@Data
public class Order extends BaseEntity {
    private Integer oid;
    private Integer uid;
    private String recvName;
    private String recvPhone;
    private String recvProvince;
    private String recvCity;
    private String recvArea;
    private String recvAddress;
    private Long totalPrice;
    private Integer status;
    private Date orderTime;
    private Date payTime;
}
  • 订单项OrderItem实体类
java 复制代码
/** 订单中的商品数据 */
@Data
public class OrderItem extends BaseEntity {
    private Integer id;
    private Integer oid;
    private Integer pid;
    private String title;
    private String image;
    private Long price;
    private Integer num;
}

3. 持久层

3.1 规划sql语句

  • 在订单表中新增数据
  • 在订单项表中新增数据

3.2 编写OrderMapper接口以及抽象方法

java 复制代码
package com.cy.store.mapper;


import com.cy.store.entity.Order;
import com.cy.store.entity.OrderItem;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface OrderMapper {
    /** 插入订单数据 */
    Integer insertOrder(Order order);

    /** 插入订单项数据 */
    Integer insertOrderItem(OrderItem orderItem);

}

3.3 sql映射

XML 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.mapper.OrderMapper">

    <!-- 插入订单数据 -->
    <insert id="insertOrder" useGeneratedKeys="true" keyProperty="oid">
        insert into t_order (
            uid, recv_name, recv_phone, recv_province, recv_city, recv_area, recv_address,
            total_price,status, order_time, pay_time, created_user, created_time, modified_user,
            modified_time
        ) values (
            #{uid}, #{recvName}, #{recvPhone}, #{recvProvince}, #{recvCity}, #{recvArea},
            #{recvAddress}, #{totalPrice}, #{status}, #{orderTime}, #{payTime}, #{createdUser},
            #{createdTime}, #{modifiedUser}, #{modifiedTime}
        )
    </insert>

    <!-- 插入订单商品数据 -->
    <insert id="insertOrderItem" useGeneratedKeys="true" keyProperty="id">
        insert into t_order_item (
            oid, pid, title, image, price, num, created_user,
            created_time, modified_user, modified_time
        ) values (
            #{oid}, #{pid}, #{title}, #{image}, #{price}, #{num}, #{createdUser},
            #{createdTime}, #{modifiedUser}, #{modifiedTime}
        )
    </insert>

</mapper>

3.4 测试类进行对mapper接口的测试

java 复制代码
@SpringBootTest
class OrderMapperTest {
    @Autowired
    private OrderMapper orderMapper;

    @Test
    void insertOrder() {
        Order order = new Order();
        order.setUid(1);
        order.setRecvName("张三");
        order.setRecvPhone("12345678901");
        order.setRecvProvince("广东省");
        order.setRecvCity("广州市");
        order.setRecvArea("海珠区");
        order.setRecvAddress("广州大学城");
        order.setStatus(0);
        orderMapper.insertOrder(order);
    }

    @Test
    void insertOrderItem() {
        OrderItem orderItem = new OrderItem();
        orderItem.setOid(1);
        orderItem.setPid(10000001);
        orderItem.setTitle("测试商品");
        orderItem.setImage("https://picsum.photos/200/300");
        orderItem.setNum(1);
        orderMapper.insertOrderItem(orderItem);

    }
}

4. 业务层

准备工作:需要在收货地址表中获取收货地址的信息,封装到订单表和订单项表中

4.1 在AddressService接口中定义根据收货地址id获取收货地址数据

java 复制代码
    /**
     * 根据收货地址id,查询收货地址详情
     * @param aid 收货地址id
     * @return 匹配的收货地址详情,如果没有匹配的数据,则返回null
     */
    Address findByAid(Integer aid,Integer uid);

4.2 在子类中实现抽象方法

java 复制代码
    /**
     * 根据收货地址id查询收货地址数据
     * @param aid 收货地址id
     * @param uid 用户id
     * @return 匹配的收货地址数据,如果没有匹配的数据则返回null
     */
    @Override
    public Address findByAid(Integer aid, Integer uid) {
        Address address = addressMapper.findByAid(aid);
        if (address==null){
            throw new AddressNotFoundException("收货地址数据不存在");
        }
        if (!address.getUid().equals(uid)){
            throw new AccessDeniedException("非法数据访问");
        }
//        将不必要的数据都设为null
        address.setProvinceCode(null);
        address.setCityCode(null);
        address.setAreaCode(null);
        address.setCreatedTime( null);
        address.setModifiedTime(null);
        address.setModifiedUser( null);
        address.setCreatedUser( null);
        return address;
    }

4.3 在OrderService中定义接口和抽象方法

java 复制代码
package com.cy.store.service;

import com.cy.store.entity.Order;

public interface OrderService {
    /**
     * 创建订单
     * @param aid 收货地址id
     * @param uid 用户id
     * @param cids 购物车数据id
     * @param username 用户名
     * @return 订单id
     */
    public Order create(Integer aid, Integer[] cids, Integer uid, String username);
}

4.4 实现类实现接口重写抽象方法

java 复制代码
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    //需要调用业务层的getByAid方法
    @Autowired
    private AddressService addressService;

    //需要调用业务层的getVOByCids方法
    @Autowired
    private CartService cartService;

    //需要调用业务层的getByUid方法
    private UserService userService;

     @Override
    public Order create(Integer aid, Integer[] cids, Integer uid, String username) {

        //返回的列表中的对象都是即将下单的
        List<CartVO> list = cartService.findVOByCid(uid, cids);

        long totalPrice = 0L;
        for (CartVO cartVO : list) {
            totalPrice += cartVO.getRealPrice()*cartVO.getNum();

        }
//         获取用户的收获地址信息
        Address address = addressService.findByAid(aid, uid);
        Order order = new Order();
//        封装到订单对象中
        order.setUid(uid);

        //封装收货地址
        order.setRecvName(address.getName());
        order.setRecvPhone(address.getPhone());
        order.setRecvProvince(address.getProvinceName());
        order.setRecvCity(address.getCityName());
        order.setRecvArea(address.getAreaName());
        order.setRecvAddress(address.getAddress());

        //封装创建时间,支付状态和总价
        order.setOrderTime(new Date());
        order.setStatus(0);
        order.setTotalPrice(totalPrice);

        //封装四个日志
        order.setCreatedUser(username);
        order.setCreatedTime(new Date());
        order.setModifiedUser(username);
        order.setModifiedTime(new Date());
        Integer rows = orderMapper.insertOrder(order);
        if (rows != 1) {
            throw new InsertException("插入数据时产生未知的异常");
        }

        //插入数据------将某条订单的所有商品的详细数据插入
        for (CartVO cartVO : list) {
            OrderItem orderItem = new OrderItem();

            /**
             * 此时获取的oid不为空,因为在配置文件里面开启了oid主
             * 键自增,所以上面的代码执行插入时就自动将oid赋值了
             */
            orderItem.setOid(order.getOid());

            orderItem.setPid(cartVO.getPid());
            orderItem.setTitle(cartVO.getTitle());
            orderItem.setImage(cartVO.getImage());
            orderItem.setPrice(cartVO.getRealPrice());
            orderItem.setNum(cartVO.getNum());

            orderItem.setCreatedUser(username);
            orderItem.setCreatedTime(new Date());
            orderItem.setModifiedUser(username);
            orderItem.setModifiedTime(new Date());

            rows = orderMapper.insertOrderItem(orderItem);
            if (rows != 1) {
                throw new InsertException("插入数据时产生未知的异常");
            }
        }
        return order;
    }


}

4.5 进行测试

java 复制代码
@SpringBootTest
class OrderServiceTest {
    @Autowired
    private OrderService orderService;

    @Test
    void create() {
        Order order = orderService.create(9, new Integer[]{4, 5, 6}, 5, "admin");
        System.out.println(order);
    }
}

5. 控制层

在OrderController类中接收前端传过来的请求,调用接口完成实现请求

java 复制代码
@RestController
@RequestMapping("/orders")
public class OrderController extends BaseController{
    @Autowired
    private OrderService orderService;

    @RequestMapping("/create")
    public JsonResult<Order> create(Integer aid, Integer[] cids, HttpSession session) {
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        Order data = orderService.create(aid, cids, uid, username);
        return new JsonResult<>(OK, data);
    }

}

6. 前端页面

在orderConfirm.html页面中点击"在线支付"按钮时,发送请求

  • $("#address-list").val() 获取 选中的地址id
  • location.search.substr(1) 拿到url拼接的参数cid
javascript 复制代码
// 点击 在线支付 按钮 点击事件
			$("#btn-create-order").click(function() {
				//获取 选中的地址id
				var aid = $("#address-list").val();//12
				// 拿到url拼接的参数cid
				var cids = location.search.substr(1);//cids=4&cids=6&cids=8
				$.ajax({
					url: "/orders/create",
					data: "aid=" + aid + "&" + cids, // aid和cid进行拼接作为请求参数传递到后端,aid=12&cids=4&cids=6&cids=8
					type: "GET",
					dataType: "JSON",
					success: function(json) {
						if (json.state == 200) {
							alert("创建订单成功!")
							location.href = "payment.html";
						} else {
							alert("创建订单失败!" + json.message);
						}
					},
					error: function(xhr) {
						alert("创建订单数据时产生未知的异常" + xhr.status);
					}
				});
			});
相关推荐
JH30737 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
Coder_Boy_9 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble9 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟9 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖9 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
qq_124987075310 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_11 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.11 小时前
Day06——权限认证-项目集成
java
瑶山11 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy11 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法