黑马瑞吉外卖day3中用ThreadLocal解决获取不到当前用户id的技巧

在数据库很多表中由于很多字段是公共的,比如创建时间,创建人id等,可以用一个元数据处理器进行公共字段的填充,该类如下:

package com.example.reggie.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler { //填充公共字段
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        long id=Thread.currentThread().getId();
        log.info("-----{}",id);

        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}

但是,这个类是获取不到当前登录用户的id的,因为它获取不到cookie,需要别的类传递给它id!

所以,该怎么解决这个id问题呢?

通过演示可知,在进行添加员工或更新员工操作时,过滤器、Controller类以及这个类使用的是同一个线程!

因此,有一个好的方法,使用ThreadLocal类(它是一个线程局部变量,每一个线程是一个作用范围)

可以创建一个线程局部变量工具类:

package com.example.reggie.common;

public class BaseContext {          //线程变量工具类
    private static ThreadLocal threadLocal=new ThreadLocal<>();

    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

在工具类中有两个静态方法,在其他类中可以使用。

在过滤器类中,当登录成功时,嵌入以下代码,获取当前登录id

Long empid=(Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(empid);

然后在其他类中,调用BaseContext.getCurrentId()方法,即可成功完成不同的类之间的id的传递!

这样就解决了一些类不能获取到当前用户id的问题。

这样也解决了在不同的类之间传递参数的问题(前提是得经过同一个线程)。

你可能感兴趣的:(瑞吉外卖,黑马程序员,java,mybatis,开发语言,springboot)