字段自动填充功能:
减少重复填充的无用代码。
实现步骤:
-
实体类中需要自动填充的属性添加@TableField属性,并设置fill属性为FieldFill.INSERT (添加时自动填充)、FieldFill.INSERT(修改时自动填充)还是FieldFill.INSERT_UPDATE(添加时、修改时自动填充)
-
定义元数据对象处理器:创建一个类实现MetaObjectHandler接口,并添加@Component注解将该类交给Springboot托管,重写insertFill和updateFill方法
-
设置自动填充字段的值:调用MetaObject对象的setValue方法,以键值对的形式设置自动填充自动值。
代码演示:
//创建时间
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//更新时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
//创建人
@TableField(fill = FieldFill.INSERT)
private Long createUser;
//修改人
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
@Component //交给Spring管理
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入操作时实现字段自动填充
@Override
public void insertFill (MetaObject metaObject) {
// 参数传入的时字段名,要设置的字段值
metaObject.setValue("createTime",LocalDateTime.now());
metaObject.setValue("createUser",BaseContext.getCurrentId());
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
// 修改操作时实现字段自动填充
@Override
public void updateFill (MetaObject metaObject) {
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
}
线程工具类:
适用场景:前端每发送一条请求,从请求的开始--->到请求结束,都由一个线程在处理。在三层架构处理请求过程中,可以在请求开始位置(放行前)设置共享线程变量值,传递给后面要用到该值的地方。请求结束后要注意remove共享线程变量。(不进行remove当线程过多会溢出)
实现步骤:
-
创建线程工具类。
-
创建ThreadLocal<>对象并设置为static
-
创建工具类的三个静态方法分别是:定义set方法调用ThreadLocal类中的set方法,返回值为void
定义get方法调用ThreadLocal类中的get方法,返回值为泛型类型
定义remove方法调用ThreadLocal类中的remove方法,返回值为void
-
移除共享线程变量:该项目请求结束是放行后所以在dofilter方法后r进行emove共享线程变量,避免共享线程在内存中过多导致内存溢出。
代码演示:
public class BaseContext {
// 创建线程工具类 一个线程可以执行多个类 通过这个特性可以使用线程来传递id
private static ThreadLocal<Long> threadLocal=new ThreadLocal<>();
// 设置共享线程变量的值
public static void setCurrentId(Long id){
threadLocal.set(id);
}
// 获取共享线程变量的值
public static Long getCurrentId(){
return threadLocal.get();
}
// 释放共享线程变量
public static void removeCurrentId(){
threadLocal.remove();
}
}
BaseContext.setCurrentId(id);
// 放行前
// 设置共享变量的值
//-----------------------------
filterChain.doFilter(request,response);
//-----------------------------
// 放行后
// 释放共享变量的值
BaseContext.removeCurrentId();
LambdaQueryWrapper构造sql条件(本质是构造sql语句):
实现步骤:
-
设置条件构造器
-
设置判断条件
-
调用聚合查询方法传入判断条件并获取该方法的返回值。
代码实现:
@Override
public R<String> remove (Long id) {
// 设置查询条件 根据id进行菜品查询
LambdaQueryWrapper<Dish> queryWrapper1=new LambdaQueryWrapper<>();
// 设置判断添加 通过传入id与实体类的id相匹配。
queryWrapper1.eq(Dish::getCategoryId,id);
// 调用count聚合查询方法 并返回统计查询结果
int count1 = dishService.count(queryWrapper1);
//如果已经关联,抛出一个业务异常
if (count1>0){
throw new CustomException("当前分类下关联了菜品,不能删除");
}
// 设置查询条件 根据id进行套餐查询
LambdaQueryWrapper<Setmeal> queryWrapper2 =new LambdaQueryWrapper<>();
// 判断传入的id是否与套餐id相关联
queryWrapper2.eq(Setmeal::getCategoryId,id);
// 调用count查询 并统计查询结果
int count2 = setmealService.count(queryWrapper2);
//如果已经关联,抛出一个业务异常
if (count2>0){
throw new CustomException("当前分类下关联了套餐,不能删除");
}
//正常删除分类
categoryMapper.deleteById(id);
return R.success("分类信息删除成功");
}