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` (`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
# 更新软件源sudo apt-get update# 安装openjdk-8-jdksudo apt-get install openjdk-8-jdk# 查看java版本java -version
openjdk 默认安装路径为 /usr/lib/jvm
,然后设置环境变量:
# 打开配置文件vi /etc/profile# 添加下列环境变量JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64JRE_HOME=$JAVA_HOME/jreCLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/libPATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/binexport JAVA_HOME JRE_HOME CLASSPATH PATH# 使环境变量生效source /etc/profile
# 安装 nginxsudo apt-get install nginx# 启动/停止/重启/重加载 nginxsudo service nginx startsudo service nginx stopsudo service nginx restartsudo 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;}
# 安装 mysqlsudo apt-get install mysql-server# 启动 mysqlmysql -u root -pYourNewPassword
安装完成后各个文件存放位置:
启动脚本:/etc/init.d/mysql数据库目录:/var/lib/mysql配置文件:/usr/share/mysql(命令及配置文件),/etc/mysql(如:my.cnf)相关命令:/usr/bin 和 /usr/sbin
cd /usr/local# 下载并解压源码wget http://download.redis.io/releases/redis-5.0.5.tar.gztar xzf redis-5.0.5.tar.gz# 编译并安装cd redis-5.0.5make install PREFIX=/usr/local/redis# 复制配置文件到安装目录mkdir /usr/local/redis/etccp /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
日志 = 日志门面(SLF4J) + 日志实现(Logback)。
使用方式一:
public class LoggerTest {private final Logger logger = LoggerFactory.getLogger(LoggerTest.class);@Testpublic void test() {logger.debug("debug...");logger.info("info...");logger.error("error...");}}
使用方式二,使用 Lombok
注解:
首先引入依赖:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
添加 @Slf4j
注解:
@Slf4jpublic class LoggerTest {@Testpublic 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/logfile: C:/Users/chanshiyu/Documents/log/sell.loglevel: 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.Driverusername: rootpassword: 1124chanshiyuurl: jdbc:mysql://127.0.0.1:3306/sell?characterEncoding=utf-8&useSSL=false&serverTimezone=UTCjpa:show-sql: trueredis:host: 127.0.0.1port: 6379
打包项目:
mvn clean package -Dmaven.test.skip=true
上传远程服务器:
scp -P 8022 target/sell.jar [email protected]:/opt/javaapps
启动:
cd /opt/javaappsjava -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
将主键生成策略修改为:
/* 类目 id */@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer categoryId;
进行列表查询,需要给 dataobject 添加无参的构造方法:
/* 列表查询时需要增加一个默认的构造器 */public ProductCategory() {}
忘记给 service 实现类添加 @Service
注解。
@Servicepublic class ProductCategoryServiceImpl implements ProductCategoryService {}
没有给 dataobject 主键添加 @Id
注解:
@Idprivate String productId;
对于 Integer、Long 类型的属性值,表单验证用的注解应该是用 @NotNull
,不能用 @NotBlank
或者 @NotEmpty
。
@Datapublic class CategoryForm {@ApiModelProperty("类目名称")@NotEmpty(message = "类目名称必填")private String categoryName;@ApiModelProperty("类目编号")@NotNull(message = "类目编号必填")private Integer categoryType;}