大连企业网站建站模板,phpstudy 网站空白,会议展厅设计装修公司,淘宝客返利网站建设公共字段自动填充 1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3 步骤三 1.4 功能测试 1.1 问题分析
在前面我们已经完成了后台系统的员工管理功能和菜品分类功能的开发#xff0c;在新增员工或者新增菜品分类时需要设置创建时间、创建人、修改时间、修… 公共字段自动填充 1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3 步骤三 1.4 功能测试 1.1 问题分析
在前面我们已经完成了后台系统的员工管理功能和菜品分类功能的开发在新增员工或者新增菜品分类时需要设置创建时间、创建人、修改时间、修改人等字段在编辑员工或者编辑菜品分类时需要设置修改时间、修改人等字段。这些字段属于公共字段也就是也就是在我们的系统中很多表中都会有这些字段如下
序号字段名含义数据类型1create_time创建时间datetime2create_user创建人idbigint3update_time修改时间datetime4update_user修改人idbigint
而针对于这些字段我们的赋值方式为
1). 在新增数据时, 将createTime、updateTime 设置为当前时间, createUser、updateUser设置为当前登录用户ID。
2). 在更新数据时, 将updateTime 设置为当前时间, updateUser设置为当前登录用户ID。
在项目中处理这些字段都是在每一个业务方法中进行赋值操作,如下:
新增员工方法 /*** 新增员工** param employeeDTO*/public void save(EmployeeDTO employeeDTO) {//.......................////设置当前记录的创建时间和修改时间employee.setCreateTime(LocalDateTime.now());employee.setUpdateTime(LocalDateTime.now());//设置当前记录创建人id和修改人idemployee.setCreateUser(BaseContext.getCurrentId());//目前写个假数据后期修改employee.setUpdateUser(BaseContext.getCurrentId());///employeeMapper.insert(employee);}编辑员工方法 /*** 编辑员工信息** param employeeDTO*/public void update(EmployeeDTO employeeDTO) {//........................................///employee.setUpdateTime(LocalDateTime.now());employee.setUpdateUser(BaseContext.getCurrentId());///employeeMapper.update(employee);}新增菜品分类方法 /*** 新增分类* param categoryDTO*/public void save(CategoryDTO categoryDTO) {//....................................////设置创建时间、修改时间、创建人、修改人category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());category.setCreateUser(BaseContext.getCurrentId());category.setUpdateUser(BaseContext.getCurrentId());///categoryMapper.insert(category);}修改菜品分类方法 /*** 修改分类* param categoryDTO*/public void update(CategoryDTO categoryDTO) {//....................................////设置修改时间、修改人category.setUpdateTime(LocalDateTime.now());category.setUpdateUser(BaseContext.getCurrentId());//categoryMapper.update(category);}如果都按照上述的操作方式来处理这些公共字段, 需要在每一个业务方法中进行操作, 编码相对冗余、繁琐那能不能对于这些公共字段在某个地方统一处理来简化开发呢
答案是可以的我们使用AOP切面编程实现功能增强来完成公共字段自动填充功能。
1.2 实现思路
在实现公共字段自动填充也就是在插入或者更新的时候为指定字段赋予指定的值使用它的好处就是可以统一对这些字段进行处理避免了重复代码。在上述的问题分析中我们提到有四个公共字段需要在新增/更新中进行赋值操作, 具体情况如下:
序号字段名含义数据类型操作类型1create_time创建时间datetimeinsert2create_user创建人idbigintinsert3update_time修改时间datetimeinsert、update4update_user修改人idbigintinsert、update
实现步骤
1). 自定义注解 AutoFill用于标识需要进行公共字段自动填充的方法
2). 自定义切面类 AutoFillAspect统一拦截加入了 AutoFill 注解的方法通过反射为公共字段赋值
3). 在 Mapper 的方法上加入 AutoFill 注解
若要实现上述步骤需掌握以下知识
技术点枚举、注解、AOP、反射
1.3 代码开发
1.3.1 步骤一
自定义注解 AutoFill
进入到sky-server模块创建com.sky.annotation包。
package com.sky.annotation;/*** 自定义注解用于标识某个方法需要进行功能字段自动填充处理*/
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
public interface AutoFill {//数据库操作类型UPDATE INSERTOperationType value();
}其中OperationType已在sky-common模块中定义
package com.sky.enumeration;/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT
}1.3.2 步骤二
自定义切面 AutoFillAspect
在sky-server模块创建com.sky.aspect包。
package com.sky.aspect;/*** 自定义切面实现公共字段自动填充处理逻辑*/
Aspect
Component
Slf4j
public class AutoFillAspect {/*** 切入点*/Pointcut(execution(* com.sky.mapper.*.*(..)) annotation(com.sky.annotation.AutoFill))public void autoFillPointCut(){}/*** 前置通知在通知中进行公共字段的赋值*/Before(autoFillPointCut())public void autoFill(JoinPoint joinPoint){/重要//可先进行调试是否能进入该方法 提前在mapper方法添加AutoFill注解log.info(开始进行公共字段自动填充...);}
}完善自定义切面 AutoFillAspect 的 autoFill 方法
package com.sky.aspect;import ......./*** 自定义切面实现公共字段自动填充处理逻辑*/
Aspect
Component
Slf4j
public class AutoFillAspect {/*** 切入点*/Pointcut(execution(* com.sky.mapper.*.*(..)) annotation(com.sky.annotation.AutoFill))public void autoFillPointCut(){}/*** 前置通知在通知中进行公共字段的赋值*/Before(autoFillPointCut())public void autoFill(JoinPoint joinPoint){log.info(开始进行公共字段自动填充...);//获取到当前被拦截的方法上的数据库操作类型MethodSignature signature (MethodSignature) joinPoint.getSignature();//方法签名对象AutoFill autoFill signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象OperationType operationType autoFill.value();//获得数据库操作类型//获取到当前被拦截的方法的参数--实体对象Object[] args joinPoint.getArgs();if(args null || args.length 0){return;}Object entity args[0];//准备赋值的数据LocalDateTime now LocalDateTime.now();Long currentId BaseContext.getCurrentId();//根据当前不同的操作类型为对应的属性通过反射来赋值if(operationType OperationType.INSERT){//为4个公共字段赋值try {Method setCreateTime entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);Method setCreateUser entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);Method setUpdateTime entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);//通过反射为对象属性赋值setCreateTime.invoke(entity,now);setCreateUser.invoke(entity,currentId);setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}else if(operationType OperationType.UPDATE){//为2个公共字段赋值try {Method setUpdateTime entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);//通过反射为对象属性赋值setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}}
}1.3.3 步骤三
在Mapper接口的方法上加入 AutoFill 注解
以CategoryMapper为例分别在新增和修改方法添加AutoFill()注解也需要EmployeeMapper做相同操作
package com.sky.mapper;Mapper
public interface CategoryMapper {/*** 插入数据* param category*/Insert(insert into category(type, name, sort, status, create_time, update_time, create_user, update_user) VALUES (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser}))AutoFill(value OperationType.INSERT)void insert(Category category);/*** 根据id修改分类* param category*/AutoFill(value OperationType.UPDATE)void update(Category category);}同时将业务层为公共字段赋值的代码注释掉。
1). 将员工管理的新增和编辑方法中的公共字段赋值的代码注释。
2). 将菜品分类管理的新增和修改方法中的公共字段赋值的代码注释。
1.4 功能测试
以新增菜品分类为例进行测试
启动项目和Nginx 查看控制台
通过观察控制台输出的SQL来确定公共字段填充是否完成
查看表
category表中数据
其中create_time,update_time,create_user,update_user字段都已完成自动填充。
由于使用admin(id1)用户登录进行菜品添加操作,故create_user,update_user都为1.
后记 美好的一天到此结束下次继续努力欲知后续请看下回分解写作不易感谢大家的支持