云快卖,提供专业好用的外卖系统、跑腿系统和同城信息系统,公众号+小程序+APP多端适用。
公共字段自动填充1.的方法及解决办法(上)
2023-02-18 22:00:37 云快卖

您的支持将是我创作的动力,让我们一起加油进步吧!!!

一、公共数组手动填充1.问题剖析

后面我们早已完成了后台系统的职工管理功能开发,在新增职工时须要设置创建时间、创建人、修改时间、修改人等数组,在编辑职工时须要设置更改时间和更改人等数组。这种数组属于公共数组,也就是好多表中都有这种数组,如下:

能不能对于这种公共数组在某个地方统一处理,来简化开发呢?

答案就是使用Plus提供的公共数组手动填充功能。

2.代码实现

Plus公共数组手动填充,也就是在插入或则更新的时侯为指定主键赋于指定的值,使用它的用处就是可以统一对这种数组进行处理,防止了重复代码。

实现步骤:

1、在实体类的属性上加入@注解,指定手动填充的策略

 @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;

2、按照框架要求编撰元数据对象处理器,在这种中统一为公共数组形参,这种须要实现插口

/**
 * 自定义元数据对象处理器
 */
@Slf4j
@Component
public class MyMetaObjecthandler implements MetaObjectHandler {
    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]...");
        log.info(metaObject.toString());
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createUser", new Long(1));
        metaObject.setValue("updateUser", new Long(1));
    }
    /**
     * 更新操作,自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]...");
        log.info(metaObject.toString());
        long id = Thread.currentThread().getId();
        log.info("线程id为:{}",id);
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", new Long(1));
    }
}

功能健全

后面我们早已完成了公共数组手动填充功能的代码开发,而且还有一个问题没有解决,就是我们在手动填充和时设置的用户id是固定值,如今我们须要改导致动态获取当前登入用户的id。

有的朋友可能想到,用户登陆成功后我们将用户id存入了中,如今我从中获取不就行了?

注意:我们在类中是不能获得对象的,所以我们须要通过其他方法来获取登陆用户id。

可以使用来解决此问题,它是JDK中提供的一个类。

在学习之前,我们须要先确认一个事情,就是顾客端发送的每次http恳求,对应的在服务端就会分配一个新的线程来处理点餐系统点餐系统,在处理过程中涉及到下边类中的方式都属于相同的一个线程:

1、的方式

2、的方式

3、的方式

可以在里面的三个方式中分别加入下边代码(获取当前线程id):

  long id = Thread.currentThread().getId();
  log.info("线程id为:{}",id);

执行编辑职工功能进行验证,通过观察控制台输出可以发觉,一次恳求对应的线程id是相同的:

哪些是?

并不是一个,而是的局部变量。当使用维护变量时,为每位使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

为每位线程提供单独一份储存空间,具有线程隔离的疗效,只有在线程内就能获取到对应的值,线程外则不能访问。

常用方式:

我们可以在的方式中获取当前登入用户id,并调用的set方式来设置当前线程的线程局部变量的值(用户id),之后在的方式中调用的get方式来获得当前线程所对应的线程局部变量的值(用户id)。

实现步骤

1、编写工具类,基于封装的工具类

/**
 * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
 */
public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
    /**
     * 设置值
     * @param id
     */
    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }
    /**
     * 获取值
     * @return
     */
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

2、在的方式中调用来设置当前登入用户的id

 if(request.getSession().getAttribute("employee") != null){
            log.info("用户已登录,用户id为:{}", request.getSession().getAttribute("employee"));
           Long empId = (Long) request.getSession().getAttribute("employee");
           BaseContext.setCurrentId(empId);
            filterChain.doFilter(request, response);

return; }

3、在的方式中调用获取登陆用户的id

@Slf4j
@Component
public class MyMetaObjecthandler implements MetaObjectHandler {
    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]...");
        log.info(metaObject.toString());
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
    /**
     * 更新操作,自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]...");
        log.info(metaObject.toString());
        long id = Thread.currentThread().getId();
        log.info("线程id为:{}",id);
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}

二、新增分类1.需求剖析

后台系统中可以管理分类信息,分类包括两种类型,分别是菜肴分类和套餐分类。当我们在后台系统中添加菜肴时须要选择一个菜肴分类,当我们在后台系统中添加一个套餐时须要选择一个套餐分类,在联通端也会根据食材分类和套餐分类来展示对应的食材和套餐。

2.数据模型

新增分类,虽然就是将我们新增窗口录入的分类数据插入到表,表结构如下:

3.代码开发4.功能测试

三、分类信息分类查询1.需求剖析

系统中的分类好多的时侯,假如在一个页面中全部展示下来会变得比较乱,不易于查看,所以通常的系统中还会以分页的形式来展示列表数据。

2.代码实现

 @GetMapping("/page")
    public R<Page> page(int page, int pageSize) {
        //分页构造器
        Page<Category> pageInfo = new Page<>(page, pageSize);
        //条件构造器
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        //添加排序条件,根据sort进行排序
        queryWrapper.orderByAsc(Category::getSort);
        //分页查询
        categoryService.page(pageInfo, queryWrapper);
        return R.success(pageInfo);
    }

3.功能测试

四、删除分类1.需求剖析

在分类管理列表页面,可以对某个分类进行删掉操作。须要注意的是当分类关联了菜肴或则套餐时,此分类不容许删掉。

2.代码实现

 	@DeleteMapping
    public R<String> delete(Long id) {
        log.info("删除分类,id为{}", id);
        categoryService.removeById(id);
        //代码完善之后categoryService.remove(id);
        return R.success("分类信息删除成功");
    }

3.代码构建

后面我们早已实现了按照id删掉分类的功能,而且并没有检测删掉的分类是否关联了菜肴或则套餐,所以我们须要进行功能健全。

要建立分类删掉功能,须要先打算基础的类和插口:

1、实体类Dish和

@Data
public class Dish implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    //菜品名称
    private String name;
    //菜品分类id
    private Long categoryId;
    //菜品价格
    private BigDecimal price;
    //商品码
    private String code;
    //图片
    private String image;
    //描述信息
    private String description;

//0 停售 1 起售 private Integer status; //顺序 private Integer sort; @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; }

@Data
public class Setmeal implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    //分类id
    private Long categoryId;
    //套餐名称
    private String name;
    //套餐价格
    private BigDecimal price;
    //状态 0:停用 1:启用
    private Integer status;
    //编码
    private String code;
    //描述信息
    private String description;
    //图片
    private String image;
    @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;
}

2、接口和

@Mapper
public interface DishMapper extends BaseMapper<Dish> {
}

@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}

3、接口和

public interface DishService extends IService<Dish> {
}

public interface SetmealService extends IService<Setmeal> {
}

4、实现类和

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
}

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
}

关键代码

五、修改分类1.需求剖析

在分类管理列表页面点击更改按键,弹出更改窗口,在更改窗口回显分类信息并进行更改,最后点击确定按键完成更改操作。

2.代码实现

 	@PutMapping
    public R<String> update(@RequestBody Category category){
        log.info("修改分类信息:{}",category);
        categoryService.updateById(category);
        return R.success("修改分类信息成功");
    }

创作不易,假如有帮助到你,请给文章点个赞和收藏,让更多的人听到!!!

关注博主不走失,内容持续更新中。

免责声明:部分文章信息来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性,如本站文章和转稿涉及版权等问题,请作者在及时联系本站,我们会尽快为您处理。

云快卖

留言咨询

×