使用Mybatis Plus提供的公共字段自动填充功能
![](https://img-blog.csdnimg.cn/img_convert/2d6a813a2817081994fe6d278ac3bce1.png)
Mybatis Plus公共字段自动填充,也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。在上述的问题分析中,我们提到有四个公共字段,需要在新增/更新中进行赋值操作 实现步骤:
1、在实体类的属性上加入@TableField注解,指定自动填充的策略。
按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。
1). 实体类的属性上加入@TableField注解,指定自动填充的策略。
在员工Employee实体类的公共字段属性上, 加上注解, 指定填充策略。
![](https://img-blog.csdnimg.cn/img_convert/3764bf19295e3f27956315319ba3795a.png)
. 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。
![](https://img-blog.csdnimg.cn/img_convert/5e21c43cfdb8cd496cb9dcd57b4f8790.png)
在数据库很多表中由于很多字段是公共的,比如创建时间,创建人id等,可以用一个元数据处理器(上面这个类)进行公共字段的填充。
但是,这个类是获取不到当前登录用户的id的,因为它获取不到cookie,需要别的类传递给它id!
所以,该怎么解决这个id问题呢?
通过演示可知,在进行添加员工或更新员工操作时,过滤器、Controller类以及这个类使用的是同一个线程!
因此,有一个好的方法,使用ThreadLocal类(它是一个线程局部变量,每一个线程是一个作用范围)
![](https://img-blog.csdnimg.cn/img_convert/8db8445ce4531d35484a6d02b518fca9.png)
![](https://img-blog.csdnimg.cn/img_convert/e53be714674ab22f890d97c01f377d8b.png)
![](https://img-blog.csdnimg.cn/img_convert/dcffa81748cd55ef063cdbc33f552de1.png)
![](https://img-blog.csdnimg.cn/img_convert/e939a2cf79178c64c5a2173f3c8d94fe.png)
通过ThreadLocal获取线程ID:
具体方法:
public void set(T value)//设置当前线程的线程局部变量的值
public T get()//返回当前线程所对应的线程局部变量的值
ThreadLocal:
在学习ThreadLocal之前,我们需要先确认一个事情,就是客户端发送的每次http请求,对应的在服务端都会分配一个新的线程来处理。在处理过程中涉及到下面类中的方法都属于相同的一个线程:
1、LoginCheckFilter的doFilter方法
2、EmployeeController的update方法
MyMetaObjectHandler的updateFill方法
什么是ThreadLocal?
ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
我们可以在LoginCheckFilter(这个类是登陆过滤器)的doFilter方法中获取当前登录用户id,并调用ThreadLocal的set方法来设置当前线程的线程局部变量的值(用户id),然后在yMetaObjectHandler的updateFill方法中调用ThreadLocall的get方法来获得当前线程所对应的线程局部变量的值(用户id)。
1、编写BaseContext工具类,基于ThreadLocal封装的工具类
![](https://img-blog.csdnimg.cn/img_convert/70a9cbbb775ea7cfc2781691bea82c60.png)
在工具类中有两个静态方法,在其他类中可以使用。
在过滤器类中,当登录成功时,嵌入以下代码,获取当前登录id
2.在LoginCheckFilter的doFilter2方法中调用BaseContext:来设置当前登录用户的id
![](https://img-blog.csdnimg.cn/img_convert/5c2bcd0c99d1f12a8c0db1a79c9f2ae1.png)
3、在MyMetaObjectHandleri的方法中调用BaseContext获取登录用户的id
![](https://img-blog.csdnimg.cn/img_convert/4db9c502a2dd6bdde8cbc420a3a7d92c.png)
然后在其他类中,调用BaseContext.getCurrentId()方法,即可成功完成不同的类之间的id的传递!
这样就解决了一些类不能获取到当前用户id的问题。
这样也解决了在不同的类之间传递参数的问题(前提是得经过同一个线程)。