使用SpringBoot+MyBatis+MySQL完成订单

创建数据表

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;

创建实体类

订单实体类

/** 订单数据的实体类 */
public class Order extends BaseEntity implements Serializable {
    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;
       // get、set、hashCode()、equals()和toString()方法 
}

订单项的实体类

/** 订单中的商品数据 */
public class OrderItem extends BaseEntity implements Serializable {
    private Integer id;
    private Integer oid;
    private Integer pid;
    private String title;
    private String image;
    private Long price;
    private Integer num;
   // get、set、hashCode()、equals()和toString()方法 
}

订单-持久层

规划SQL语句

将数据插入到订单表中。

insert into t_order (oid除外的所有字段) values (字段的值)

将数据插入到订单项的表中。

insert into t_order_item (id除外的所有字段) values (字段的值)

设计接口和抽象方法

创建一个OrderMapper接口,接口中添加以上两个SQL对象的方法。

package com.cy.store.mapper;

import com.cy.store.entity.Order;
import com.cy.store.entity.OrderItem;

public interface OrderMapper {
    /**
     * 插入订单数据
     * @param order 订单数据
     * @return 受影响的行数
     */

    Integer insertOrder(Order order);

    /** 
     * 插入订单项数据
     * @param orderItem 订单项数据
     * @return 受影响的行数
     */
    Integer insertOrderItem(OrderItem orderItem);
}

SQL映射

创建OrderMapper.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">
<!-- namespace属性:用于指定当前的映射文件和哪个接口进行映射,需要指定接口的文件路径,需要标注包的完整路径 -->
<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>

单元测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class OrderMapperTests {
    @Autowired
    private OrderMapper orderMapper;

    @Test
    public void insertOrder() {
        Order order = new Order();
        order.setUid(13);
        order.setRecvName("花花");
        order.setRecvPhone("18656879807");
        orderMapper.insertOrder(order);
    }

    @Test
    public void insertOrderItem() {
        OrderItem orderItem = new OrderItem();
        orderItem.setOid(1);
        orderItem.setPid(10000022);
        orderItem.setTitle("联想(Lenovo)IdeaPad310经典版黑色");
        orderMapper.insertOrderItem(orderItem);
    }
}

订单-业务层

在IAddressService接口中定义根据收货地址的id获取收货地址数据。

Address getByAid(Integer aid);

在子类中实现该抽象方法。

    @Override
    public Address getByAid(Integer aid, Integer uid) {
        Address address = addressMapper.findByAid(aid);
        if (address == null) {
            throw new AddressNotFoundException("收货地址数据不存在");
        }
        if (!address.getUid().equals(uid)) {
            throw new AccessDeniedException("非法数据访问");
        }
        address.setProvinceCode(null);
        address.setCityCode(null);
        address.setAreaCode(null);
        address.setCreatedUser(null);
        address.setCreatedTime(null);
        address.setModifiedUser(null);
        address.setModifiedTime(null);
        return address;
    }

在Service包下创建IOrderService接口添加抽象方法用于创建订单。

public interface IOderService {
    Order create(Integer aid, Integer uid, String username, Integer[] cids);
}

创建实现类OrderServiceImpl类。

@Service
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IAddressService addressService;
    @Autowired
    private ICartService cartService;

    @Override
    public Order create(Integer aid, Integer uid, String username, Integer[] cids) {
        // 即将要下单的列表
        List<CartVO> list = cartService.getVOByCid(uid, cids);
        // 计算产品总价
        Long totalPrice = 0L;
        for (CartVO c : list) {
            totalPrice += c.getRealPrice() * c.getNum();
        }
        Address address = addressService.getByAid(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.setStatus(0);
        order.setTotalPrice(totalPrice);
        order.setOrderTime(new Date());
        // 日志
        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 c : list) {
            // 创建一个订单项数据
            OrderItem orderItem = new OrderItem();
            orderItem.setOid(order.getOid());
            orderItem.setPid(c.getPid());
            orderItem.setTitle(c.getTitle());
            orderItem.setImage(c.getImage());
            orderItem.setPrice(c.getRealPrice());
            orderItem.setNum(c.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;
    }
}

单元测试

测试技巧:测试的时候需要先去t_address中找地址,然后填入比如14,14,“test001”,三个值后,需要再去t_cart中,找属于test001用户的cid;
或者先去t_cart中查看都有属于哪个用户的,然后去t_address中查看是否有该用户的收货地址,没有的话可以添加一个。

@SpringBootTest
@RunWith(SpringRunner.class)
public class OrderServiceTests {
    @Autowired
    private IOrderService orderService;

    @Test
    public void create() {
        Integer[] cids = {1,3,4};
        Order order = orderService.create(14, 14, "test001", cids);
        System.out.println(order);
    }
}

订单-控制层

设计请求

请求路径:/orders/create
请求方法:POST
请求数据:Integer aid,HttpSession session, Integer[] cids
响应结果:JsonResult<Order>

实现请求

创建OrderController类,并编写请求处理方法。

@RestController
@RequestMapping("orders")
public class OrderController extends BaseController{
    @Autowired
    private IOrderService 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, uid, username, cids);
        return new JsonResult<>(OK, data);
    }
}

单元测试

重启项目、登录后,输入url进行验证。

订单-前端页面

在订单确定页面(orderConfirm.html)中添加发送请求的方法。

$("#btn-create-order").click(function () {
				let aid = $("#address-list").val();
				let cids = location.search.substring(1); // cids=2&cids=3
				$.ajax({
					url: "/orders/create",
					type: "GET",
					data: "aid=" + aid + "&" + cids, // aid=12&cids=2&cids=3
					dataType: "JSON",
					success: function (json) {
						if (json.state == 200) {
							location.href = "payment.html";
							alert("订单创建成功");
							console.log(json.data);
						}
					},
					error: function (xhr) {
						alert("订单数据加载时产生未知的异常," + xhr.status);
					}
				});
			});

测试

重启项目、登录后,进入购物车,选择商品,点击结算再点在线支付按钮进行验证。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我无法提供具体的免费源码。但是,我可以为你提供一些指导来帮助你搭建基于Vue2、Element、Spring BootMyBatis-Plus和MySQL的商城系统。 首先,你可以按照以下步骤进行开发: 1. 设置前端项目:使用Vue CLI创建一个新的Vue项目并安装Element UI库,这将为你提供用户界面组件和样式。 2. 开发前端页面:根据商城的需求,设计和开发前端页面,包括商品列表、购物车、订单等功能。使用Element UI的组件和样式来构建用户友好的界面。 3. 创建后端项目:使用Spring Initializr创建一个新的Spring Boot项目,并添加必要的依赖,如Spring Web、MyBatis-Plus和MySQL驱动程序。 4. 配置数据库:在MySQL中创建一个数据库,并配置Spring Boot应用程序的数据库连接。使用MyBatis-Plus来简化数据库操作,包括数据表映射、CRUD操作等。 5. 开发后端接口:根据商城的需求,设计和开发后端接口,包括商品查询、购物车管理、订单处理等功能。使用Spring Boot的注解来定义RESTful API,并调用MyBatis-Plus进行数据库操作。 6. 前后端交互:通过HTTP请求将前端页面与后端接口连接起来。在Vue项目中使用Axios库来发送和接收数据,并处理响应结果。 7. 测试和部署:对商城系统进行测试,确保功能正常运行。使用适当的工具和平台,将前端和后端部署到生产环境中。 请注意,这只是一个大致的指导,具体的实现细节可能会因项目需求和个人偏好而有所不同。你需要根据自己的情况进行适当的调整和扩展。如果你在具体实现中遇到问题,可以随时向我提问,我会尽力帮助你。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值