电商生鲜网站开发(一)——Spring Boot项目开发准备

62 篇文章 3 订阅

本系列内容完成Spring Boot框架的电商生鲜网站开发的完整案例,前后端分离开发的案例,先开发后端接口后开发前端,最后部署等待。

Spring Boot项目开发准备

IDEA web开发必备插件

Maven Helper 与Maven一起工作的必备插件

Free Mybatis Tool 帮助我们跳转和识别Mapper中的一些语法错误

2022.7.7 - 发现MybaitsX也不错很好用,方便XML跳转和SQL生成
https://baomidou.com/pages/ba5b24/#%E5%8A%9F%E8%83%BD

Postman安装——接口自测

帮助我们开发时接口自测的调试工具,免费
在这里插入图片描述

MySQL可视化工具——mac平台

Sequel pro for mac是Mac os平台上的一款帮助用户快速连接SQL数据库的开源免费Mac软件

http://sequelpro.com/test-builds

在连接MySQL时可能会出现问题:MySQL said: Authentication plugin ‘caching_sha2_password’ cannot be loaded

这会初始化数据库,数据库有数据的话请一定备份😭

打开系偏好设置-MySQL-Initialize Database-输入设置的密码-勾选Use Legacy Password Encryption-启动MySQL

数据库设计

案例:

/*
 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 80026
 Source Host           : localhost:3306
 Source Schema         : fresh_mall

 Target Server Type    : MySQL
 Target Server Version : 80026
 File Encoding         : 65001
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for mall_cart
-- ----------------------------
DROP TABLE IF EXISTS `mall_cart`;
CREATE TABLE `mall_cart` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '购物车id',
  `product_id` int NOT NULL COMMENT '商品id',
  `user_id` int NOT NULL COMMENT '用户id',
  `quantity` int NOT NULL DEFAULT '1' COMMENT '商品数量',
  `selected` int NOT NULL DEFAULT '1' 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 (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='购物车';

-- ----------------------------
-- Table structure for mall_category
-- ----------------------------
DROP TABLE IF EXISTS `mall_category`;
CREATE TABLE `mall_category` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL DEFAULT '' COMMENT '分类目录名称',
  `type` int NOT NULL COMMENT '分类目录级别,例如1代表一级,2代表二级,3代表三级',
  `parent_id` int NOT NULL COMMENT '父id,也就是上一级目录的id,如果是一级目录,那么父id为0',
  `order_num` 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 (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品分类 ';

-- ----------------------------
-- Table structure for mall_order
-- ----------------------------
DROP TABLE IF EXISTS `mall_order`;
CREATE TABLE `mall_order` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `order_no` varchar(128) NOT NULL DEFAULT '' COMMENT '订单号(非主键id)',
  `user_id` int NOT NULL COMMENT '用户id',
  `total_price` int NOT NULL COMMENT '订单总价格',
  `receiver_name` varchar(32) NOT NULL COMMENT '收货人姓名快照',
  `receiver_mobile` varchar(32) NOT NULL COMMENT '收货人手机号快照',
  `receiver_address` varchar(128) NOT NULL DEFAULT '' COMMENT '收货地址快照',
  `order_status` int NOT NULL DEFAULT '10' COMMENT '订单状态: 0用户已取消,10未付款(初始状态),20已付款,30已发货,40交易完成',
  `postage` int DEFAULT '0' COMMENT '运费,默认为0',
  `payment_type` int NOT NULL DEFAULT '1' COMMENT '支付类型,1-在线支付',
  `delivery_time` timestamp NULL DEFAULT NULL COMMENT '发货时间',
  `pay_time` timestamp NULL DEFAULT NULL COMMENT '支付时间',
  `end_time` timestamp NULL DEFAULT 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 (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单表;';

-- ----------------------------
-- Table structure for mall_order_item
-- ----------------------------
DROP TABLE IF EXISTS `mall_order_item`;
CREATE TABLE `mall_order_item` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `order_no` varchar(128) NOT NULL DEFAULT '' COMMENT '归属订单id',
  `product_id` int NOT NULL COMMENT '商品id',
  `product_name` varchar(100) NOT NULL DEFAULT '' COMMENT '商品名称',
  `product_img` varchar(128) NOT NULL DEFAULT '' COMMENT '商品图片',
  `unit_price` int NOT NULL COMMENT '单价(下单时的快照)',
  `quantity` int NOT NULL DEFAULT '1' COMMENT '商品数量',
  `total_price` int NOT NULL DEFAULT '0' 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 (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单的商品表 ';

-- ----------------------------
-- Table structure for mall_product
-- ----------------------------
DROP TABLE IF EXISTS `mall_product`;
CREATE TABLE `mall_product` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '商品主键id',
  `name` varchar(100) NOT NULL COMMENT '商品名称',
  `image` varchar(500) NOT NULL DEFAULT '' COMMENT '产品图片,相对路径地址',
  `detail` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '商品详情',
  `category_id` int NOT NULL COMMENT '分类id',
  `price` int NOT NULL COMMENT '价格,单位-分',
  `stock` int NOT NULL COMMENT '库存数量',
  `status` int NOT NULL DEFAULT '1' 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 (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品表';

-- ----------------------------
-- Table structure for mall_user
-- ----------------------------
DROP TABLE IF EXISTS `mall_user`;
CREATE TABLE `mall_user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `username` varchar(32) NOT NULL DEFAULT '' COMMENT '用户名',
  `password` varchar(50) NOT NULL COMMENT '用户密码,MD5加密',
  `personalized_signature` varchar(50) NOT NULL DEFAULT '' COMMENT '个性签名',
  `role` int NOT NULL DEFAULT '1' COMMENT '角色,1-普通用户,2-管理员',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表 ';

SET FOREIGN_KEY_CHECKS = 1;

项目初始化–依赖引入pom

pom.xml sprintboot版本2.2.1.RELEASE

<!--引入依赖-->
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>1.3.2</version>
</dependency>

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>

<--插件配置-->
  <plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.7</version>
    <configuration>
      <verbose>true</verbose>
      <overwrite>true</overwrite>
    </configuration>
  </plugin>

自动创建实体类和mapper

利用mybatis-generator自动创建实体类和mapper

resources下创建generatorConfig.xml

配置mysql-connector-java-8.0.18.jar在你电脑存放的路径,我这里都放入resources

配置数据库连接

配置生成Model类存放位置

配置生成mapper映射文件存放位置

配置生成Dao类存放位置

配置生成对应表及类名

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
  <!-- 配置文件,放在resource目录下即可 -->
  <!--数据库驱动个人配置-->
  <classPathEntry
    location="/Users/cat/Documents/fresh-mall/src/main/resources/mysql-connector-java-8.0.18.jar"/>
  <context id="MysqlTables" targetRuntime="MyBatis3">
    <property name="autoDelimitKeywords" value="true"/>
    <!--可以使用``包括字段名,避免字段名与sql保留字冲突报错-->
    <property name="beginningDelimiter" value="`"/>
    <property name="endingDelimiter" value="`"/>
    <!-- optional,旨在创建class时,对注释进行控制 -->
    <commentGenerator>
      <property name="suppressDate" value="true"/>
      <property name="suppressAllComments" value="true"/>
    </commentGenerator>
    <!--数据库链接地址账号密码-->
    <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
      connectionURL="jdbc:mysql://127.0.0.1:3306/fresh_mall?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"
      userId="root"
      password="root1024">
      <property name="nullCatalogMeansCurrent" value="true"/>
    </jdbcConnection>
    <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
    <javaTypeResolver>
      <property name="forceBigDecimals" value="false"/>
    </javaTypeResolver>
    <!--生成Model类存放位置-->
    <javaModelGenerator targetPackage="com.learn2333.freshmall.model.pojo"
      targetProject="src/main/java">
      <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
      <property name="enableSubPackages" value="true"/>
      <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
      <property name="trimStrings" value="true"/>
      <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
      <property name="immutable" value="false"/>
    </javaModelGenerator>
    <!--生成mapper映射文件存放位置-->
    <sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
      <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>
    <!--生成Dao类存放位置-->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.learn2333.freshmall.model.dao"
      targetProject="src/main/java">
      <property name="enableSubPackages" value="true"/>
    </javaClientGenerator>
    <!--生成对应表及类名-->
    <table schema="root" tableName="mall_cart" domainObjectName="Cart"
      enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>
    <table tableName="mall_category" domainObjectName="Category" enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>
    <table tableName="mall_order" domainObjectName="Order" enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>
    <table tableName="mall_order_item" domainObjectName="OrderItem"
      enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>
    <table tableName="mall_product" domainObjectName="Product" enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>
    <table tableName="mall_user" domainObjectName="User" enableCountByExample="false"
      enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
      selectByExampleQueryId="false">
    </table>

  </context>
</generatorConfiguration>

点击右侧mavan中的插件–这个插件是因为上面pom中配置的才生效的

会自动生成mapper和实体类
在这里插入图片描述

在生成的mapper接口和mapper.xml文件中左侧行号右边会有互相跳转的箭头,这是配置的IDEA插件Free Mybatis Tool 生效了

在这里插入图片描述

配置项目的数据库连接

application.properties

server.port=8080
spring.datasource.name=fresh_mall
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/fresh_mall?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root1024
#mapper的位置
mybatis.mapper-locations=classpath:mappers/*.xml

Application启动类配置dao mapper接口的注解路径

@MapperScan(basePackages = "com.learn2333.freshmall.model.dao")

创建测试类

controller.UserController

package com.learn2333.freshmall.controller;

import com.learn2333.freshmall.model.pojo.User;
import com.learn2333.freshmall.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 用户控制器
 */
@Controller
public class UserController {
    @Autowired
    UserService userService;

    @GetMapping("/test")
    @ResponseBody
    public User personalPage() {
        return userService.getUser();
    }
}

service.UserService接口

package com.learn2333.freshmall.service;

import com.learn2333.freshmall.model.pojo.User;

public interface UserService {
    User getUser();
}

service.impl.UserServiceImpl实现类

package com.learn2333.freshmall.service.impl;

import com.learn2333.freshmall.model.dao.UserMapper;
import com.learn2333.freshmall.model.pojo.User;
import com.learn2333.freshmall.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public User getUser() {
        return userMapper.selectByPrimaryKey(1);
    }
}

运行后访问test即可获得数据,连接成功

但是此时在代码中:引入的mapper会被标红,但仍可正常运行

    @Autowired
    UserMapper userMapper;

这是因为编译器无法自动识别mapper,因为mapper是在springboot入口@MapperScan(basePackages = "com.learn2333.freshmall.model.dao")配置的,这是为了给mybatis识别用的,而编译器无法识别,解决方案可以在dao下的mapper接口上增加注解@Repositor,这样IDEA就会认为@Autowired进来的mapper是一个资源。

log4j2日志的引入

日志级别:error, warn,info,debug,trace(依次向下级别递减)

排除之前的日志组件Logback依赖

pom.xml

<!--在spring-boot-starter-web使用exclusions排除自带的组件-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>  
<!--引入log4j2-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

配置日志组件

log4j2.xml

配置日志文件保存的位置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
  <Properties>
    <!--    日志文件保存位置 mac,linux系统下此目录代表当前登录用户目录下的logs目录-->
    <Property name="baseDir" value="${sys:user.home}/logs"/>
  </Properties>

  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
      <ThresholdFilter level="info" onMatch="ACCEPT"
                       onMismatch="DENY"/>
      <PatternLayout
              pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
    </Console>

    <!--debug级别日志文件输出 此处引用的${baseDir}是上面定义过的name的value-->
    <RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
                 filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
      <!-- 过滤器 -->
      <Filters>
        <!-- 限制日志级别在debug及以上在info以下 -->
        <ThresholdFilter level="debug"/>
        <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
      </Filters>
      <!-- 日志格式 -->
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <!-- 策略 -->
      <Policies>
        <!-- 每隔一天转存 (每天新生成一个文件)-->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 文件大小 -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>

    <!-- info级别日志文件输出 -->
    <RollingFile name="info_appender" fileName="${baseDir}/info.log"
                 filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
      <!-- 过滤器 -->
      <Filters>
        <!-- 限制日志级别在info及以上在error以下 -->
        <ThresholdFilter level="info"/>
        <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
      </Filters>
      <!-- 日志格式 -->
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <!-- 策略 -->
      <Policies>
        <!-- 每隔一天转存 -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 文件大小 -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>

    <!-- error级别日志文件输出 -->
    <RollingFile name="error_appender" fileName="${baseDir}/error.log"
                 filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
      <!-- 过滤器 -->
      <Filters>
        <!-- 限制日志级别在error及以上 -->
        <ThresholdFilter level="error"/>
      </Filters>
      <!-- 日志格式 -->
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <Policies>
        <!-- 每隔一天转存 -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 文件大小 -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>

    <logger name="org.springframework" level="info"
            additivity="true">
      <AppenderRef ref="Console" />
      <AppenderRef ref="MyFile" />
    </logger>

    <!-- 控制台打印的级别配置 -->
    <Root level="debug">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="debug_appender"/>
      <AppenderRef ref="info_appender"/>
      <AppenderRef ref="error_appender"/>
    </Root>

  </Loggers>
</Configuration>

运行项目,可以看到在配置好的文件路径下生成了日志
在这里插入图片描述

打开控制台使用tail -f 文件名可以打印出文件新增加的内容

在这里插入图片描述

访问一个请求,内容也会相应变化,可以用这个方法调试程序。

AOP统一处理Web请求日志

是对系统健壮性的一个保护,利用fitter把每一个请求打印出来,提高开发和调试的效率

目的:创建fitter,把请求和响应信息打印出来

pom引入aop

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

fitter.WebLogAspect.java 直接创建fitter类,利用注解配合方法实现自定义请求和响应日志的输出

package com.learn2333.freshmall.fitter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * 打印请求和响应信息
 */
@Aspect
@Component
public class WebLogAspect {
    private final Logger log = LoggerFactory.getLogger(WebLogAspect.class);

    //指定拦截点
    @Pointcut("execution(public * com.learn2333.freshmall.controller.*.*(..))")
    public void webLog() {

    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        //收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //记录日志
        //url
        log.info("URL : " + request.getRequestURI().toString());
        //请求类型
        log.info("HTTP_METHOD : " + request.getMethod());
        //ip
        log.info("IP : " + request.getRemoteAddr());
        //类的方法
        log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        //参数
        log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(returning = "res", pointcut = "webLog()")
    public void doAfterReturn(Object res) throws JsonProcessingException {
        //处理完请求,返回内容
        //writeValueAsString是fastjson提供的一个将对象转成json格式的工具
        log.info("RESPONSE : " + new ObjectMapper().writeValueAsString(res));
    }
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
这份资源是一个基于SpringBoot+Vue的生鲜超市管理系统的完整开发源码,包括前端、后端、数据库等部分。该系统主要用于生鲜超市的管理,包括商品管理、库存管理、销售管理等功能。该系统支持管理员、销售员、仓库管理员等多个角色,并可以实现数据报表、数据分析、销售预测等功能。 为了更好地使用本资源,我们提供了详细的部署说明和系统介绍。在部署说明中,我们详细介绍了如何将本资源部署到本地或远程服务器上,并配置相关环境参数。在系统介绍中,我们对生鲜超市管理系统的各项功能、前后端框架和技术栈进行了详细介绍和解释,以帮助开发者更好地理解系统设计思路和功能实现。 对于想要深入学习和了解源码的开发者,我们还提供了源码解释。通过逐行分析源码,我们对系统的技术实现、API设计、业务逻辑等进行深入解读和分析,帮助开发者更好地理解源码和在其基础上进行二次开发,并提供更多开发思路和技巧。 总之,本资源适合对SpringBoot、Vue、生鲜超市管理系统开发有一定基础的开发者学习和参考。生鲜超市管理系统设计思路、技术实现和业务逻辑等方面都具有高参考价值,为开发者提供了实践和实现超市管理的宝贵经验和思路。该系统可用于优化超市管理流程、提高管理效率,也可拓展至其他类似的零售行业中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摘星喵Pro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值