java项目之瑞吉外卖(未完结)

361 阅读7分钟

注: 本章内容深度只针对个人😅,不喜勿喷💢。内容如有理解上的错误,望能指出,这将对于小白很有用😇。

项目结构分析

image.png
在项目中上方框出来的四个很常见,那么它们分别代表什么呢?

entity(实体)
实体类,通常代表一个具体的对象或数据模型。它可以是数据库中的表、领域模型中的对象,或者是用于表示某个概念的类
Mapper(映射器)
用于将数据从持久化存储(如数据库)中检索出来或将数据写入持久化存储的组件。通常用于持续数据库操作,如查询、插入、更新、删除。
Service(服务)
用于实现业务逻辑的组件,通常包含一些方法,用于处理数据和执行特定的业务操作。Service可以调用Mapper来访问数据库。并将数据处理后的返回给控制器或其他组件。
SercviceImpl(服务实现)
Service接口的具体实现类。包含了实现业务逻辑的具体代码,通过调用Mapper来访问数据库,并对数据进行处理和操作。
Controller(控制器)
处理用户请求并返回响应的组件。接受用户的请求,调用相应的Service方法来处理请求,并将处理结果返回给用户。Controller通常用于处理URL映射、请求参数解析、调用Service等操作。 image.png 可参考: blog.csdn.net/m0_73311735…
@Mapper注解 : 一般写在dao/mapper层,映射xml配置文件
@Service注解 : 一般写在Sevice实现类中(即SeviceImpl),会将当前类自动注入到spring容中

常用推荐

前端

常用方法

获取浏览器地址

  • location.href

split 将字符串分成一个有序的子串列表,将字串放入数组,并返回
针对: 字符串

substring 返回一个字符串在开始索引到结束索引之间的一个子集,或从开始索引直到字符串的末尾的一个子集。
针对: 字符串

indexOf 返回第一次出现元素的下标,不存在则返回-1
针对: 字符串、数组

reverse 反转数组中的元素
针对: 数组

join 将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串
针对: 数组

replace 将匹配到的value替换成某值
针对: 数组

localStorage 将存储的数据保存在浏览器会话中,直到会话关闭
针对: 浏览器

后端

常用类、方法

获取当前时间

  • LocalDateTime.now()

md5加密

value: xxx

  • DigestUtils.md5DigestAsHex("xxx".getBytes())

session的创建、获取与移除

自定义工具类

返回结果类

package com.xhpa.demo.common;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class R<T> {

    private Integer code; //编码:1成功,0和其它数字为失败

    private String msg; //错误信息

    private T data; //数据

    private Map map = new HashMap(); //动态数据

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}

项目经验

前端

axios传递参数的不同方式

简介:Axios是基于promise*网络请求库

1.请求参类型params

image.png 下方图片注意的那块不使用 data: {...params} 请求的时候,参数将会作为属性值进行传递,所以后端可以直接写参数值 image.png image.png image.png

2. 请求参数类型Json

image.png 这块通过data:{...params},将参数作为一个json对象进行传递给了后端 employee,因为接受的是json对象,所以使用的注解@RequestBody image.png

注意:这样写,获取接口地址的参数为 image.png 改为 1 中的写法则为 image.png

image.png

3. 直接在url中传递动态参数

这里写法的想法是因为确定只有一个id,所以不带参数,直接将参数放在了url地址上传递,同时需要注意,因为是地址栏,所以后端获取参数的时候,需要添加注解@ PathVariable image.png image.png image.png

=、==、===的区别

单等号 = : 只在赋值时使用
双等号 == : 比较运算符。当两边数据类型相同,会判断两值是否相等;当两数据类型不同,会自动转换为相同类型,在进行比较。简称放水性比较
三等号 === : 比较运算符。既要判断数据类型是否相同,也要判断值是否相同。相对于==,非常严格

后端

用maven构建项目时resources目录就是默认的ClassPath

classPath即为java文件编译之后的class文件的编译目录一般为web-inf/classes,src下的xml在编译时也会复制到classPath下

GetMapping/PostMapping/PutMapping/DeleteMapping的选择

  • GetMapping: 页面获取数据量不大时使用
  • PostMapping: 添加数据时使用
  • PutMapping: 修改数据时使用
  • DeleteMapping:删除数据时使用

解析MybatisPlus自动填充字段功能

  1. 在实体类需要自动填充的字段上添加
    @TableField(fill = FieldFill.INSERT) 意思是在添加时,会自动添加这个字段。
    FieldFill枚举类还有如下四种,可自行选择 image.png

2.创建工具类并实现MetaObjectHandler,自定义自动添加的值

@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
//这里与原课程有些变动,因为开始没有跟着课程写拦截器,
//造成了我登陆后所获得的线程与添加修改后的线程不一样。
//以至于无法通过将登录id放入同一线程并获取,
//所以这里通过 `@Resource`/`@Autowired` 将HttpServletRequest自动注入,
//在通过request.getSession.getAttribute("employee"),来获取前面存入的登录id
    
    @Resource
    private HttpServletRequest request;

    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createUser", request.getSession().getAttribute("employee"));
        metaObject.setValue("updateUser", request.getSession().getAttribute("employee"));
    }

打印日志

  1. 引入pom依赖 image.png
  2. 类上方引入注解 image.png
  3. 使用 image.png

线程的使用

公共字段自动填充 课程部分。

对于页面修改操作,因为处于同一线程,所以思路是将登录用户id存到线程当中(在之前,是将修改人用户id存到session中,从session中获取存入的值),当我们需要用到这个id时,可以直接从线程当中获取

查看当前线程: 可写在不同操作地方,用来查看当前操作是否在同一线程当中 image.png

Thread.currentThread().getId();

项目中使用了 ThreadLocal,原因是它为每一个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问
注意:必须强制回收自己的ThreadLocal

常用方法
public void set(T value) 设置当前线程的线程局部变量的值
public T get() 返回当前线程所对应的线程局部变量的值

实现步骤
1、对ThreadLocal类进行封装

// ThreadLocal工具类,用户保存和获取登录用户id
public class BaseContext {
    //因为要使用ThreadLocal中的方法,所以要创建这个对象,通过thread获取类中的属性方法等等
    private static final ThreadLocal<Long> thread = new ThreadLocal<>();

    //取出id
    public static Long getCurrentId() {
        return thread.get();    //主要代码
    }
    //在线程中存入id
    public static void setCurrentId(Long id) {
        thread.set(id);    //主要代码
    }
}

2、 获取id并放入线程,从线程中获取

存入的id: BaseContext.setCurrentId(xxx);
获取id:BaseContext.getCurrentId()

不同数据类型转换

int转Long类型

Long精度缺失

1、在实体类的缺失精度的字段上加入@JsonFormat(shape = >JsonFormat.Shape.STRING)
2、在实体类的缺失精度的字段上加入@JsonSerialize(using = ToStringSerializer.class)
3、在application.yml配置中添加
   spring:
     jackson:
       generator:
         writeNumbersAsStrings: true
4、添加全局配置类
@Configuration
public class JacksonConfig { 
 //重点
 @Bean
 @Primary
 @ConditionalOnMissingBean(ObjectMapper.class)
 public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder >builder)
 {
   ObjectMapper objectMapper = builder.createXmlMapper(false).build();
   // 全局配置序列化返回 JSON 处理
   SimpleModule simpleModule = new SimpleModule();
   //JSON Long ==> String
   simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
   objectMapper.registerModule(simpleModule);
   return objectMapper;
 }
}            

使用LocalDateTime为变量数据类型时会出现的问题

image.png 问题一:
正常应该是:
image.png
但是前端返回数据确是,如下,可以看出返回是list格式
image.png
解决办法
添加:@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") image.png

程序包lombok.extern.slf4j不存在问题如何解决

问题解决:blog.csdn.net/weixin_4364…