😄
xlzy520
  • README
  • 执笔
    • 2017
      • 01 网站动态标题的两种方式
      • 02 RN App 外部唤醒踩坑记
    • 2018
      • 01 图片加解密二三事
      • 02 优雅实现 BackTop
      • 03 Vue 一键导出 PDF
      • 04 不一样の烟火
      • 05 Python 之禅
      • 06 Python 文件操作
    • 2019
      • 01 Aurora 食用指南
      • 02 Godaddy 域名找回记事
      • 03 一个接口的诞生
      • 04 SpringMVC 前后端传参协调
      • 05 主题集成友链访问统计功能
      • 06 Github Style 博客主题
      • 07 动态加载 JS 文件
      • 08 WebSocket 心跳重连机制
      • 09 洗牌算法实现数组乱序
      • 10 React Hook 定时器
      • 11 Fetch data with React Hooks
      • 12 字符编码の小常识
      • 13 WSL 安装 Docker 实录
      • 14 Eriri comic reader
  • 书斋
    • ES6 标准入门
      • 01 变量声明与解构赋值
      • 02 语法的扩展
      • 03 数据类型与数据结构
      • 04 Proxy 和 Reflect
      • 05 异步编程 Promise
      • 06 Iterator 和 for of 循环
      • 07 Generator 函数
      • 08 Async 函数
      • 09 Class 类
    • JavaScript 设计模式
      • 01 基础知识
      • 02 设计模式(上)
      • 03 设计模式(下)
      • 04 设计原则和编程技巧
  • 前端
    • JavaScript
      • 01 JavaScript 秘密花园
      • 02 JavaScript 正则技巧
      • 03 从浏览器解析 JS 运行机制
      • 04 Canvas 基础用法
      • 05 Flex 弹性布局
      • 06 Blob Url And Data Url
      • 07 函数节流与函数防抖
      • 08 排序算法初探
    • Node
      • 01 Node Tips
      • 02 七天学会 NodeJS
    • Note
      • 01 Note
      • 02 Snippets
      • 03 Interview
      • 04 Git
      • 05 Docker
      • 06 Line
    • React
      • 01 React Props Children 传值
      • 02 Use a Render Prop!
      • 03 React Hook
      • 04 React 和 Vue 中 key 的作用
    • Vue
      • 01 Vue Tips
      • 02 Vue 构建项目写入配置文件
      • 03 Vue 项目引入 SVG 图标
  • 后端
    • Java
      • 01 浅析 Java 反射
      • 02 Java 服务端分层模型
    • Note
      • 01 Note
      • 02 Linux
      • 03 MySQL
    • Spring
      • 01 Spring Boot
      • 02 Spring Data
      • 03 JPA
      • 04 Swagger
      • 05 AOP
      • 06 SSM
    • Project
      • 01 微信点餐系统
由 GitBook 提供支持
在本页
  • 项目设计
  • 环境搭建
  • 安装 jdk
  • 安装 nginx
  • 安装 mysql
  • 安装 redis
  • 日志 Logback
  • 数据库与缓存
  • 打包部署
  • Error
  • 001 Table 'sell.hibernate_sequence' doesn't exist. could not read a hi value.
  • 002 No default constructor for entity
  • 003 Could not autowire. No beans of 'ProductInfoServiceImpl' type found.
  • 004 Error creating bean with name 'entityManagerFactory' defined in class path resource.
  • 005 No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.Integer'.

这有帮助吗?

  1. 后端
  2. Project

01 微信点餐系统

上一页Project

最后更新于5年前

这有帮助吗?

项目设计

架构部署
数据库设计
create table `product_info` (
  `product_id` varchar(32) not null,
  `product_name` varchar(64) not null comment '商品名称',
  `product_price` decimal(8,2) not null comment '商品单价',
  `product_stock` int not null comment '商品库存',
  `product_description` varchar(64) comment '商品描述',
  `product_icon` varchar(512) comment '商品小图',
  `product_status` int not null default 0 comment '商品状态,0正常 1下架',
  `category_type` int not null comment '类目编号',
  `create_time` timestamp not null default current_timestamp comment '创建时间',
  `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
  primary key (`product_id`)
) comment '商品表';

create table `product_category` (
  `category_id` int not null auto_increment,
  `category_name` varchar(64) not null comment '类目名称',
  `category_type` int not null comment '类目编号',
  `create_time` timestamp not null default current_timestamp comment '创建时间',
  `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
  primary key (`category_id`),
  unique key `uqe_category_type` (`category_type`)
) comment '类目表';

create table `order_master` (
  `order_id` varchar(32) not null,
  `buyer_name` varchar(32) not null comment '买家名字',
  `buyer_phone` varchar(32) not null comment '买家电话',
  `buyer_address` varchar(128) not null comment '买家地址',
  `buyer_openid` varchar(64) not null comment '买家微信openid',
  `order_amount` decimal(8,2) not null comment '订单金额',
  `order_status` tinyint(3) not null default '0' comment '订单状态,0新订单 1已取消 2已完结',
  `pay_status` tinyint(3) not null default '0' comment '支付状态,0待支付 1已支付',
  `create_time` timestamp not null default current_timestamp comment '创建时间',
  `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
  primary key (`order_id`),
  key `idx_buyer_openid` (`buyer_openid`)
) comment '订单主表';

create table `order_detail` (
  `detail_id` varchar(32) not null,
  `order_id` varchar(32) not null comment '订单id',
  `product_id` varchar(32) not null comment '商品id',
  `product_name` varchar(64) not null comment '商品名称',
  `product_quantity` int not null comment '商品数量',
  `product_icon` varchar(512) comment '商品小图',
  `create_time` timestamp not null default current_timestamp comment '创建时间',
  `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
  primary key (`detail_id`),
  key `idx_order_openid` (`order_id`)
) comment '订单详情表';

create table `seller_info` (
  `seller_id` varchar(32) not null,
  `username` varchar(32) not null comment '用户名',
  `password` varchar(32) not null comment '密码',
  `openid` varchar(32) not null comment '卖家openid',
  `state` tinyint(3) not null comment '账号状态,0正常 1已封禁',
  `create_time` timestamp not null default current_timestamp comment '创建时间',
  `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
  primary key (`seller_id`)
) comment '卖家信息表';

环境搭建

  • jdk

  • nginx

  • mysql

  • redis

安装 jdk

# 更新软件源
sudo apt-get update

# 安装openjdk-8-jdk
sudo apt-get install openjdk-8-jdk

# 查看java版本
java -version

openjdk 默认安装路径为 /usr/lib/jvm,然后设置环境变量:

# 打开配置文件
vi /etc/profile

# 添加下列环境变量
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
JRE_HOME=$JAVA_HOME/jre
CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASSPATH PATH

# 使环境变量生效
source /etc/profile

安装 nginx

# 安装 nginx
sudo apt-get install nginx

# 启动/停止/重启/重加载 nginx
sudo service nginx start
sudo service nginx stop
sudo service nginx restart
sudo service nginx reload

需要注意重启和重加载的区别:

  • restart 重启 nginx 服务,重启会造成服务一瞬间的中断,如果配置文件出错会导致服务启动失败,那就是更长时间的服务中断。

  • reload 重新加载配置文件,nginx 服务不会中断,而且 reload 时会测试 conf 语法等,如果出错会 rollback 用上一次正确配置文件保持正常运行。

启动后访问 http://localhost/ 检测是否正常。安装完成后各个文件存放位置:

配置文件:/etc/nginx
主程序:/usr/sbin/nginx
静态文件:/usr/share/nginx
日志:/var/log/nginx

Linux 系统的配置文件一般放在 /etc,日志一般放在 /var/log,运行的程序一般放在 /usr/sbin 或者 /usr/bin。

最后需要设置反代跨域:

location / {
    proxy_pass http://127.0.0.1:8080/;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers X-Requested-With;
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}

安装 mysql

# 安装 mysql
sudo apt-get install mysql-server

# 启动 mysql
mysql -u root -pYourNewPassword

安装完成后各个文件存放位置:

启动脚本:/etc/init.d/mysql
数据库目录:/var/lib/mysql
配置文件:/usr/share/mysql(命令及配置文件),/etc/mysql(如:my.cnf)
相关命令:/usr/bin 和 /usr/sbin

安装 redis

cd /usr/local

# 下载并解压源码
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar xzf redis-5.0.5.tar.gz

# 编译并安装
cd redis-5.0.5
make install PREFIX=/usr/local/redis

# 复制配置文件到安装目录
mkdir /usr/local/redis/etc
cp /usr/local/redis-5.0.5/redis.conf /usr/local/redis/etc

# 启动
cd /usr/local/redis
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

# 连接 redis
/usr/local/redis/bin/redis-cli

# 关闭
/usr/local/redis/bin/redis-cli shutdown

日志 Logback

日志 = 日志门面(SLF4J) + 日志实现(Logback)。

使用方式一:

public class LoggerTest {

    private final Logger logger = LoggerFactory.getLogger(LoggerTest.class);

    @Test
    public void test() {
        logger.debug("debug...");
        logger.info("info...");
        logger.error("error...");
    }
}

使用方式二,使用 Lombok 注解:

首先引入依赖:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

添加 @Slf4j 注解:

@Slf4j
public class LoggerTest {
    @Test
    public void test() {
        log.debug("debug...");
        log.info("info...");
        log.error("error...");
    }
}

日志配置方式:

  • application.yml

  • logback-spring.xml

application.yml 中进行简单配置:

logging:
  pattern:
    console: '%d - %msg%n'
  # path: C:/Users/chanshiyu/Documents/log
  file: C:/Users/chanshiyu/Documents/log/sell.log
  level: debug

但更推荐在 logback-spring.xml 中配置,可以更加细致地控制日志输出:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <!-- 控制台输出配置 -->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d - %msg%n</pattern>
        </layout>
    </appender>

    <!-- Info 日志文件配置 -->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤 Error 级别日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>Error</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <pattern>%d - %msg%n</pattern>
        </encoder>
        <!-- 滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 路径 -->
            <fileNamePattern>C:/Users/chanshiyu/Documents/log/sell/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!-- Error 日志文件配置 -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤 Info 级别日志-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>Error</level>
        </filter>
        <encoder>
            <pattern>%d - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>C:/Users/chanshiyu/Documents/log/sell/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!-- 将上述配置引入并控制日志级别 -->
    <root level="info">
        <appender-ref ref="consoleLog" />
        <appender-ref ref="fileInfoLog" />
        <appender-ref ref="fileErrorLog" />
    </root>
</configuration>

数据库与缓存

引入依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置 application.yml:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 1124chanshiyu
    url: jdbc:mysql://127.0.0.1:3306/sell?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
  jpa:
    show-sql: true
  redis:
    host: 127.0.0.1
    port: 6379

打包部署

打包项目:

mvn clean package -Dmaven.test.skip=true

上传远程服务器:

scp -P 8022 target/sell.jar root@127.0.0.1:/opt/javaapps

启动:

cd /opt/javaapps
java -jar sell.jar

# 指定端口和环境
java -jar -Dserver.port=8090 -Dspring.profiles.active=prod sell.jar

# 后台运行
nohup java -jar -Dspring.profiles.active=prod sell.jar > /dev/null 2>&1 &
# 查看进行
ps -ef |grep sell.jar
# 杀死进程
kill -9 1700

Error

001 Table 'sell.hibernate_sequence' doesn't exist. could not read a hi value.

将主键生成策略修改为:

/* 类目 id */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer categoryId;

002 No default constructor for entity

进行列表查询,需要给 dataobject 添加无参的构造方法:

/* 列表查询时需要增加一个默认的构造器 */
public ProductCategory() {}

003 Could not autowire. No beans of 'ProductInfoServiceImpl' type found.

忘记给 service 实现类添加 @Service 注解。

@Service
public class ProductCategoryServiceImpl implements ProductCategoryService {}

004 Error creating bean with name 'entityManagerFactory' defined in class path resource.

没有给 dataobject 主键添加 @Id 注解:

@Id
private String productId;

005 No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.Integer'.

对于 Integer、Long 类型的属性值,表单验证用的注解应该是用 @NotNull,不能用 @NotBlank 或者 @NotEmpty。

@Data
public class CategoryForm {

    @ApiModelProperty("类目名称")
    @NotEmpty(message = "类目名称必填")
    private String categoryName;

    @ApiModelProperty("类目编号")
    @NotNull(message = "类目编号必填")
    private Integer categoryType;
}