搭建JAVA电商平台——后端

目录

 

1.前言

2.正文

程序框架

数据库

代码结构

代码

结语


1.前言

电商是当今最火爆的一种商业模式,学习springMVC等网页后端技术的我们,都很难找得到相关的实例,而往往很多公司在招聘的时候都会或多或少地要求有电商平台开发的相关经验。而笔者的一个朋友分享了一个电商平台的前端代码,但是后端代码是没有的,笔者找到了一小部分,但是是无法支撑整个电商平台的运行,于是,笔者只能自己分析前端的代码再去推敲出后端的逻辑,也许你能在网上找到有相似的网站,但是内部逻辑也许是不尽相同的。

接下来我们上几张效果图大家看看,如果有兴趣再往下读。

项目的展示地址:http://www.grammaker.cn:8080/dist/view/user-login.html

项目源码地址在文末


2.正文

程序框架

用户浏览商品——加入到购物车——生成订单——支付——发货——完成 


数据库

talk is cheap ,show me the code。数据库是一切系统的基础,程序是数据结构+算法。而我觉得,数据结构的基础就是数据库的设计。 

首先,作为一个电商系统,我们需要的是用户,那么我们就首先需要一个用户表 

DROP TABLE IF EXISTS `mmall_user`;
CREATE TABLE `mmall_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户表id',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(50) NOT NULL COMMENT '用户密码,MD5加密',
  `email` varchar(50) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `question` varchar(100) DEFAULT NULL COMMENT '找回密码问题',
  `answer` varchar(100) DEFAULT NULL COMMENT '找回密码答案',
  `role` int(4) NOT NULL COMMENT '角色0-管理员,1-普通用户',
  `wechat_openid` varchar(255) DEFAULT NULL, 微信的openid
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '最后一次更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_name_unique` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8;

接下来作为一个电商平台我们当然是以产品为主

DROP TABLE IF EXISTS `mmall_product`;
CREATE TABLE `mmall_product` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
  `category_id` int(11) NOT NULL COMMENT '分类id,对应mmall_category表的主键',
  `activity_id` int(11) DEFAULT NULL,
  `name` varchar(100) NOT NULL COMMENT '商品名称',
  `subtitle` varchar(200) DEFAULT NULL COMMENT '商品副标题',
  `main_image` varchar(500) DEFAULT NULL COMMENT '产品主图,url相对地址',
  `sub_images` text COMMENT '图片地址,json格式,扩展用',
  `detail` text COMMENT '商品详情',
  `price` decimal(20,2) NOT NULL COMMENT '价格,单位-元保留两位小数',
  `stock` int(11) NOT NULL COMMENT '库存数量',
  `status` int(6) DEFAULT '1' COMMENT '商品状态.1-在售 2-下架 3-删除',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;

对于产品,我们通常为了更好的进行管理,会对其进行分品类,所以一个品类表是必不可少的

DROP TABLE IF EXISTS `mmall_category`;
CREATE TABLE `mmall_category` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '类别Id',
  `parent_id` int(11) DEFAULT NULL COMMENT '父类别id当id=0时说明是根节点,一级类别',
  `name` varchar(50) DEFAULT NULL COMMENT '类别名称',
  `status` tinyint(1) DEFAULT '1' COMMENT '类别状态1-正常,2-已废弃',
  `sort_order` int(4) DEFAULT NULL COMMENT '排序编号,同类展示顺序,数值相等则自然排序',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `main_image` varchar(500) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100053 DEFAULT CHARSET=utf8;

有了品类,产品以及用户,那么自然就是我们作为电商系统的一个最重要也是业务最繁忙的表,订单表

DROP TABLE IF EXISTS `mmall_order`;
CREATE TABLE `mmall_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单id',
  `order_no` bigint(20) DEFAULT NULL COMMENT '订单号',
  `user_id` int(11) DEFAULT NULL COMMENT '用户id',
  `shipping_id` int(11) DEFAULT NULL,
  `payment` decimal(20,2) DEFAULT NULL COMMENT '实际付款金额,单位是元,保留两位小数',
  `payment_type` int(4) DEFAULT NULL COMMENT '支付类型,1-在线支付',
  `postage` int(10) DEFAULT NULL COMMENT '运费,单位是元',
  `status` int(10) DEFAULT NULL COMMENT '订单状态:0-已取消-10-未付款,20-已付款,40-已发货,50-交易成功,60-交易关闭',
  `payment_time` datetime DEFAULT NULL COMMENT '支付时间',
  `send_time` datetime DEFAULT NULL COMMENT '发货时间',
  `end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
  `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `order_no_index` (`order_no`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=145 DEFAULT CHARSET=utf8;

大概几个核心的数据表就是这样,剩下的一些不那么重要的表我们就不在这里放出了。

在上面的表结构当中我们看到了,主要的关系是通过user_id去维系。


代码结构

大概根据主流的分层结构MVC

  • controller这个大家都熟知是web层的逻辑处理层
  • dao就是我们的数据库控制层,对于数据库的控制我们都会在这里编写
  • pojo所有orm的实体类我们都存放在这里

另外一些我们就不在这里详解了

代码

对于代码,其实在这里我需要讲的也并不多,因为都是一些业务逻辑的问题,在这里也不需要太多的解析,需要了解的话可以到文末我提供的GitHub地址去pull下来或者star一下大家自己就可以去领会了,但是有必要说几个需要注意的地方,在此篇我们就说两个类

为什么要特意抽出这两个类来解析一下呢。因为我们这个电商系统是完全前后端分离的,但是我们系统往往是有一个团队或者是多个开发者共同合作完成的,但是既然是前后端完全分离那么我们自然就是要规定好统一返回到前端的格式。才能够更好的开展开发工作,那么众口难调,对于不同开发者来说,喜欢用的状态或者结构都不尽相同,另外就是每次都要重复编写返回代码是非常麻烦的。所以我们这两个类就是统一了返回结果,作为不同模块的开发者我们只需要调用就可以返回一个规范的返回结果了,也省去了重复代码的编写,那么接下来我们来看看这两个类吧

package com.ppmall.common;

import java.io.IOException;
import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 服务response封装工具
 * @author rex
 *
 * @param <T>
 */
@JsonInclude(JsonInclude.Include.NON_NULL) // 这是Jackson的一个注解,是排除为空的字段
public class ServerResponse<T> implements Serializable {
// 在这里我们运用了泛型,那么可以很好确保尽管是不同类型的对象需要返回到前端都可以很好地进行格式化
   /**
    * 状态
    */
	private int status;
	
	/**
	 * 返回消息
	 */
    private String msg;
    
    /**
     * 返回数据(泛型)
     */
    private T data;
    
    public ServerResponse() {
		// TODO Auto-generated constructor stub
    	// 用于GenericJacksonSerializable 反序列化
	}

    private ServerResponse(int status) {
        this.status = status;
    }

    private ServerResponse(int status, String msg) {
        this.status = status;
        this.msg = msg;
    }

    private ServerResponse(int status, String msg, T data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    private ServerResponse(int status, T data) {
        this.status = status;
        this.data = data;
    }

    @JsonIgnore
    public boolean isSuccess() {
        return this.status == ResponseCode.SUCCESS.getCode();
    }

    public int getStatus() {
        return this.status;
    }

    public String getMsg() {
        return this.msg;
    }

    public T getData() {
        return this.data;
    }

    /**
     * 创建一个只有成功状态的response
     * @return
     */
    public static <T> ServerResponse<T> createSuccess() {
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode());
    }

    /**
     * 创建一个带成功信息的response
     * @return
     */
    public static <T> ServerResponse<T> createSuccessMessage(String msg) {
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(), msg);
    }

    /**
     * 创建一个带消息以及数据的response
     * @return
     */
    public static <T> ServerResponse<T> createSuccess(String msg, T data) {
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(), msg, data);
    }
    
    /**
     * 创建一个只有数据的response
     * @return
     */
    public static <T> ServerResponse<T> createSuccess(T data) {
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(), data);
    }

    /**
     * 创建一个错误状态的response
     * @return
     */
    public static <T> ServerResponse<T> createError(){
        return new ServerResponse<T>(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getDesc());
    }

    /**
     * 创建一个带错误消息的response
     * @return
     */
    public static <T> ServerResponse<T> createErrorMessage(String errorMsg){
        return new ServerResponse<T>(ResponseCode.ERROR.getCode(),errorMsg);
    }

    /**
     * 创建一个自定义错误状态与消息的response
     * @param status
     * @param errorMsg
     * @return
     */
    public static <T> ServerResponse<T> createErrorStatus(int status,String errorMsg){
        return new ServerResponse<T>(status,errorMsg);
    }
    
    public static <T> ServerResponse<T> createErrorStatus(ResponseCode code){
        return new ServerResponse<T>(code.getCode(),code.getDesc());
    }

    
    @Override
    public String toString() {
    	// jackson序列化
        ObjectMapper mapper = new ObjectMapper();
        try {
            String returnString =  mapper.writeValueAsString(this);
            return returnString;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.toString();
    }
}

这里运用到了java的泛型以及函数重载。既然已经定义好那么我们在开发的时候只需要简单的调用就可以了

if (user == null) {
    return ServerResponse.createErrorMessage("用户名或密码错误");
	      }
// todo 密碼MD5
return ServerResponse.createSuccess("登陆成功", user);
{
    "status": 0,
    "msg": "登陆成功",
    "data":{
        "id": 34,
        "username": "test",
        "password": "02C75FB22C75B23DC963C7EB91A062CC",
        "email": "fff@sss.cof",
        "phone": "13252566523",
        "question": "test",
        "answer": "test",
        "role": 0,
        "wechatOpenid": null,
        "createTime": 1528124324000,
        "updateTime": 1528124324000
    }
}

上边就是返回的结果,根据ServerResponse这个类的几个静态方法我们只是会改变里面的数据,格式是恒定不变的。

结语

好了,以上就是我们一个简单的电商平台的简单部分,只讲述了简单的一些数据结构以及比较重要的类,至于一些配置还有核心代码逻辑我们会在接下来分期进行解析,喜欢的朋友们可以继续关注。在最后,放出这个项目的GitHub地址,里面有详细的代码,有兴趣的朋友可以Star一下。这是本人的第一篇博客,写的不好请多多包涵。

https://github.com/AkiraRex/ppmall-server(GitHub)

https://gitee.com/AkiraRex/ppmall-server(码云)

关注爱养猫的程序狗可以最快获取系列更新哦

java项目之购物商城买家前后台全套(电商系统毕业设计项目指导)

11-24
1、学会各类开发软件安装、项目导入以及项目发布,含项目源码,需求文档,配套软件等 2、该项目主要功能完善,主要用于简历项目经验丰富,以及毕业设计或者二次开发 3、提供项目源码,设计文档、数据库sql文件以及所有配套软件,按照教程即可轻松实现项目安装部署 本课程为素材版,需要实战版的同学可以点击如下链接: 项目实战课程:代码视频讲解版如下 java项目实战之电商系统全套(前台和后台)(java毕业设计ssm框架项目) https://edu.csdn.net/course/detail/25771 java项目之oa办公管理系统(java毕业设计) https://edu.csdn.net/course/detail/23008 java项目之hrm人事管理项目(java毕业设计) https://edu.csdn.net/course/detail/23007 JavaWeb项目实战之点餐系统前台 https://edu.csdn.net/course/detail/20543 JavaWeb项目实战之点餐系统后台 https://edu.csdn.net/course/detail/19572 JavaWeb项目实战之宿舍管理系统(Java毕业设计含源码) https://edu.csdn.net/course/detail/26721 JavaWeb项目实战之点餐系统全套(前台和后台) https://edu.csdn.net/course/detail/20610 java项目实战之电子商城后台(java毕业设计SSM框架项目) https://edu.csdn.net/course/detail/25770 java美妆商城项目|在线购书系统(java毕业设计项目ssm版) https://edu.csdn.net/course/detail/23989 系统学习课程: JavaSE基础全套视频(环境搭建 面向对象 正则表达式 IO流 多线程 网络编程 java10 https://edu.csdn.net/course/detail/26941 Java Web从入门到电商项目实战挑战万元高薪(javaweb教程) https://edu.csdn.net/course/detail/25976其他素材版(毕业设计或课程设计)项目:点击老师头像进行相关课程学习

微信公众平台企业号开发Java版第4课——管理通讯录与发送消息

02-16

微信公众平台企业号开发Java版第2课——接收消息与响应消息

01-26
©️2020 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值