8网站免费建站,互联网小程序开发,如何创建自己的博客网站,做企业推广的公司mybatis-plus自动填充时间的配置类实现 在实际操作过程中#xff0c;我们并不希望创建时间、修改时间这些来手动进行#xff0c;而是希望通过自动化来完成#xff0c;而mybatis-plus则也提供了自动填充功能来实现这一操作#xff0c;接下来#xff0c;就来了解一下mybatis…mybatis-plus自动填充时间的配置类实现 在实际操作过程中我们并不希望创建时间、修改时间这些来手动进行而是希望通过自动化来完成而mybatis-plus则也提供了自动填充功能来实现这一操作接下来就来了解一下mybatis-plus的自动填充功能是如何进行操作的。 文章目录 mybatis-plus自动填充时间的配置类实现1. 目标2. 上代码2.1. 代码目录2.2. pom文件2.4. MyMetaObjectHandler(重点)2.5. MybatisAutoConfiguration2.6. UserContextHolder2.7. BaseEntity2.8. User 3. 测试3.1. insert(User3.2. update(User3.3. updateUpdateWrapper(更新失败3.4. updateUpdateWrapper(更新失败3.5. userServiceUpdateUpdateWrapper() 更新失败3.6. userServiceUpdateLambdaUpdateWrapper() 更新失败 4. 改造上面测试更新失败的4.1. 增加UpdateWapperAspect切面(重点)4.2. 测试updateUpdateWrapper(更新成功4.3. 测试updateUpdateWrapper(更新成功4.4. userServiceUpdateUpdateWrapper() 更新成功3.6. userServiceUpdateLambdaUpdateWrapper() 更新成功 5.总结 1. 目标
实现默认设置创建者id创建者用户名更新者id更新者用户名,创建时间更新时间实现自定义字段birth_day 没有设置值的时候设置当前时间实现自定义字段login_time没有设置值的时候更新设置当前时间
sql信息如下
drop table if exists liu_user;
CREATE TABLE liu_user (
id int(11) NOT NULL AUTO_INCREMENT COMMENT id,
username varchar(255) DEFAULT NULL COMMENT 名字,
password varchar(255) DEFAULT NULL COMMENT 密码,
phone varchar(255) DEFAULT NULL COMMENT 电话号码,
birth_day timestamp NULL COMMENT 出生时间,
login_time timestamp NULL COMMENT 登录时间,
create_by varchar(20) DEFAULT NULL COMMENT 创建者id,
create_by_name varchar(100) DEFAULT NULL COMMENT 创建者账号名,
update_by varchar(20) DEFAULT NULL COMMENT 更新者id,
update_by_name varchar(100) DEFAULT NULL COMMENT 更新者账号名,
create_time timestamp NULL COMMENT 创建时间,
update_time timestamp NULL COMMENT 更新时间,
PRIMARY KEY (id)
) COMMENT用户表;2. 上代码
2.1. 代码目录 2.2. pom文件 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- Tag-单元测试 junit--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependency!-- aop切面 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIdtransmittable-thread-local/artifactIdversion2.14.3/version/dependencydependencygroupIdorg.testng/groupIdartifactIdtestng/artifactIdversion6.14.3/version/dependency!-- Tag-单元测试 junit--!-- Tag-mybatis plus--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.3.1/version/dependency!-- Tag-mybatis plus--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.47/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.28/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdscopetest/scope/dependency2.3. yml配置
spring:datasource:# mysqldriver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://192.168.0.154:3306/bigdata_src1?useUnicodetruecharacterEncodingUTF-8zeroDateTimeBehaviorconvertToNullallowMultiQueriestrueuseSSLfalse
mybatis-plus:mapper-locations: classpath*:com/liuhm/dao/mysqlmapper/*Mapper.xml# 实体扫描多个package用逗号或者分号分隔type-aliases-package: com.liuhm.entityglobal-config:db-config:id-type: autofield-strategy: not_nulllogic-delete-value: 0logic-not-delete-value: 0banner: falseconfiguration:#sql日志打印log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: truecache-enabled: falseserver:port: 90992.4. MyMetaObjectHandler(重点)
常规实现MetaObjectHandler
package com.liuhm.config;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.liuhm.config.context.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.lang.reflect.Field;
import java.util.*;/*** ClassNameSmMetaObjectHandler* Description: 全局处理基本字段* Author: liuhaomin* Date: 2023/11/29 15:25*/
Slf4j
Component
public class MyMetaObjectHandler implements MetaObjectHandler {private final ListString userIdFieldList new ArrayList(Arrays.asList(createBy, updateBy));private final ListString userNameFieldList new ArrayList(Arrays.asList(createByName, updateByName));private final String updateBy updateBy;private final String updateByName updateByName;private final static String JAVA_LANG_OBJECT java.lang.object;Overridepublic void insertFill(MetaObject metaObject){try {setDefaultValue(metaObject, Arrays.asList(FieldFill.INSERT, FieldFill.INSERT_UPDATE));} catch (Exception e) {log.warn(设置默认参数失败 {});}}Overridepublic void updateFill(MetaObject metaObject){try {setDefaultValue(metaObject, Arrays.asList(FieldFill.INSERT_UPDATE, FieldFill.UPDATE));} catch (Exception e) {log.warn(设置默认参数失败 {});}}public void setDefaultValue(MetaObject metaObject, ListFieldFill fieldFills){ListField declaredFields new ArrayList();Class tempClass metaObject.getOriginalObject().getClass();while(tempClass ! null !tempClass.getName().toLowerCase().equals(JAVA_LANG_OBJECT)){declaredFields.addAll(Arrays.asList(tempClass.getDeclaredFields()));tempClass tempClass.getSuperclass();}String userId UserContextHolder.getUserId();String userName UserContextHolder.getUserName();Date date new Date();String fieldName null;Object val null;for(Field declaredField : declaredFields){fieldName declaredField.getName();val getFieldValByName(fieldName, metaObject);TableField annotation declaredField.getAnnotation(TableField.class);if (Objects.nonNull(annotation) (fieldFills.contains(annotation.fill()))) {if (Objects.isNull(val)) {if (userIdFieldList.contains(fieldName) Objects.nonNull(userId)) {val userId;}if (userNameFieldList.contains(fieldName) Objects.nonNull(userName)) {val userName;}// 插入的时候符合条件的 为空设置值// 设置符合条件的默认时间if (Date.equals(declaredField.getType().getSimpleName())) {val date;}} else {// 更新if (updateBy.equals(fieldName) Objects.nonNull(userId)) {val userId;}if (updateByName.equals(fieldName) Objects.nonNull(userName)) {val userName;}}if(fieldFills.contains(FieldFill.INSERT_UPDATE) fieldFills.contains(FieldFill.UPDATE)){// 设置符合条件的默认时间if (Date.equals(declaredField.getType().getSimpleName())) {val date;}}setFieldValByName(fieldName, val, metaObject);}}}}
2.5. MybatisAutoConfiguration
package com.liuhm.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;/*** mybatis 自动配置类** author liuhaomin* date 2023.11.16*/
Configuration
MapperScan(com.liuhm.dao.mapper*)
public class MybatisAutoConfiguration {
}2.6. UserContextHolder
package com.liuhm.config.context;import com.alibaba.ttl.TransmittableThreadLocal;/*** 模拟用户获取用户名和用户信息 上下文 Holder*/
public class UserContextHolder {/*** 当前用户编号*/private static final ThreadLocalString USER_ID new TransmittableThreadLocal();private static final ThreadLocalString USER_NAME new TransmittableThreadLocal();/*** 获得用户编号。** return 用户编号*/public static String getUserId() {return USER_ID.get();}public static void setUserId(String userId) {USER_ID.set(userId);}public static void clear() {USER_ID.remove();USER_NAME.remove();}public static String getUserName() {return USER_NAME.get();}public static void setUserName(String userName) {USER_NAME.set(userName);}
}
2.7. BaseEntity
package com.liuhm.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** ClassNameBaseEntity* Description: 基础的类* Author: liuhaomin* Date: 2023/11/29 15:17*/Data
public class BaseEntity implements Serializable {private static final long serialVersionUID -995832545980280226L;/*** 创建时间*/TableField(fill FieldFill.INSERT)private Date createTime;/*** 最后更新时间*/TableField(fill FieldFill.INSERT_UPDATE)private Date updateTime;/*** 创建者目前使用 User 的 id 编号*/TableField(fill FieldFill.INSERT)private String createBy;TableField(fill FieldFill.INSERT)private String createByName;/*** 更新者目前使用 User 的 id 编号*/TableField(fill FieldFill.INSERT_UPDATE)private String updateBy;TableField(fill FieldFill.INSERT_UPDATE)private String updateByName;/*** 是否删除*/// TableLogic// private Boolean deleted;}
2.8. User
package com.liuhm.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** ClassNameUser* Description: User* Author: liuhaomin* Date: 2024/12/23 13:50*/
Data
AllArgsConstructor
NoArgsConstructor
TableName(value liu_user)
public class User extends BaseEntity {private static final long serialVersionUID -1L;private Integer id;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 电话号码*/private String phone;/*** 出生时间*/TableField(fill FieldFill.INSERT)private Date birthDay;/*** 登录时间*/TableField(fill FieldFill.UPDATE)private Date loginTime;
}
2.9. 其余简单的类
public interface UserService extends IServiceUser
public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService
public interface UserMapper extends BaseMapperUser3. 测试
3.1. insert(User
实现默认设置创建者id创建者用户名更新者id更新者用户名,创建时间更新时间birth_day 默认有数据 Testpublic void insert(){String userId 1;String userName admin;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);User user new User();user.setUsername(admin);user.setPassword(123456);user.setPhone(15723219655);userMapper.insert(user);ListUser users userMapper.selectList(null);log.info(users:{}, users);}3.2. update(User
更新者id更新者用户名更新时间login_time 默认有数据 Testpublic void update(){String userId 2;String userName admin2;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);User user userMapper.selectOne(new LambdaQueryWrapperUser().eq(User::getUsername, admin));user.setPassword(123456789);userMapper.updateById(user);ListUser users userMapper.selectList(null);log.info(users:{}, users);}3.3. updateUpdateWrapper(更新失败
更新者id更新者用户名更新时间Password更新失败 Testpublic void updateUpdateWrapper(){String userId 3;String userName admin3;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userMapper.update(null, new UpdateWrapperUser().lambda().set(User::getPassword,963852741).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(updateUpdateWrapper:{}, users);}3.4. updateUpdateWrapper(更新失败
更新者id更新者用户名更新时间Password更新失败 Testpublic void updateLambdaUpdateWrapper(){String userId 4;String userName admin4;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userMapper.update(null, new LambdaUpdateWrapperUser().set(User::getPassword,963852741123465).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(updateLambdaUpdateWrapper:{}, users);} 3.5. userServiceUpdateUpdateWrapper() 更新失败
更新者id更新者用户名更新时间Password更新失败 Testpublic void userServiceUpdateUpdateWrapper(){String userId 5;String userName admin5;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userService.update( new UpdateWrapperUser().lambda().set(User::getPassword,963852741).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(userServiceUpdateUpdateWrapper:{}, users);}3.6. userServiceUpdateLambdaUpdateWrapper() 更新失败
更新者id更新者用户名更新时间Password更新失败
Testpublic void userServiceUpdateLambdaUpdateWrapper(){String userId 6;String userName admin6;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userService.update( new LambdaUpdateWrapperUser().set(User::getPassword,963852741123465).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(userServiceUpdateLambdaUpdateWrapper:{}, users);}4. 改造上面测试更新失败的
4.1. 增加UpdateWapperAspect切面(重点)
package com.liuhm.config.acpect;import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.liuhm.config.context.UserContextHolder;
import com.liuhm.entity.BaseEntity;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;/*** ClassNameUpdateWapperAspect* Description: 解决update(Wrapper updateWrapper)自动填充不生效问题* Author: liuhaomin* Date: 2024/2/19 9:19*/
Aspect
Component
Slf4j
public class UpdateWapperAspect{Pointcut(execution(* com.baomidou.mybatisplus.core.mapper.BaseMapper.update(..)))public void pointcut(){}Around(value pointcut())public Object around(ProceedingJoinPoint pjp){updateEntity(pjp);try {return pjp.proceed();} catch (Throwable e) {throw new RuntimeException(e);}}/*** 重写update(WrapperT updateWrapper), 更新时自动填充不生效问题** param pjp** return*/private void updateEntity(ProceedingJoinPoint pjp){Object[] args pjp.getArgs();if (args ! null args.length 2) {if(args[0] ! null){return;}Object arg args[1];String userId UserContextHolder.getUserId();String userName UserContextHolder.getUserName();if (arg instanceof UpdateWrapper) {UpdateWrapper updateWrapper (UpdateWrapper) arg;String sqlSet updateWrapper.getSqlSet();if(!sqlSet.contains(update_time)){updateWrapper.set(update_time, new Date());}if (Objects.nonNull(userId) !sqlSet.contains(update_by)) {updateWrapper.set(update_by, userId);}if (Objects.nonNull(userName) !sqlSet.contains(update_by_name)) {updateWrapper.set(update_by_name, userName);}}if (arg instanceof LambdaUpdateWrapper) {LambdaUpdateWrapperBaseEntity updateWrapper (LambdaUpdateWrapper) arg;String sqlSet updateWrapper.getSqlSet();if(!sqlSet.contains(update_time)){updateWrapper.set(BaseEntity::getUpdateTime, new Date());}if (Objects.nonNull(userId) !sqlSet.contains(update_by)) {updateWrapper.set(BaseEntity::getUpdateBy, userId);}if (Objects.nonNull(userName) !sqlSet.contains(update_by_name)) {updateWrapper.set(BaseEntity::getUpdateByName, userName);}}}}
}4.2. 测试updateUpdateWrapper(更新成功
更新者id更新者用户名更新时间Password Testpublic void updateUpdateWrapper(){String userId 3;String userName admin3;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userMapper.update(null, new UpdateWrapperUser().lambda().set(User::getPassword,963852741).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(updateUpdateWrapper:{}, users);}4.3. 测试updateUpdateWrapper(更新成功
更新者id更新者用户名更新时间Password Testpublic void updateLambdaUpdateWrapper(){String userId 4;String userName admin4;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userMapper.update(null, new LambdaUpdateWrapperUser().set(User::getPassword,963852741123465).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(updateLambdaUpdateWrapper:{}, users);} 4.4. userServiceUpdateUpdateWrapper() 更新成功
更新者id更新者用户名更新时间Password Testpublic void userServiceUpdateUpdateWrapper(){String userId 5;String userName admin5;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userService.update( new UpdateWrapperUser().lambda().set(User::getPassword,963852741).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(userServiceUpdateUpdateWrapper:{}, users);}3.6. userServiceUpdateLambdaUpdateWrapper() 更新成功
更新者id更新者用户名更新时间Password Testpublic void userServiceUpdateLambdaUpdateWrapper(){String userId 6;String userName admin6;// 设置上下文模拟请求中的用户信息UserContextHolder.setUserId(userId);UserContextHolder.setUserName(userName);userService.update( new LambdaUpdateWrapperUser().set(User::getPassword,963852741123465).eq(User::getUsername, admin));ListUser users userMapper.selectList(null);log.info(userServiceUpdateLambdaUpdateWrapper:{}, users);}5.总结
实现默认设置创建者id创建者用户名更新者id更新者用户名,创建时间更新时间
自定义mapperXml sql暂时不会默认更新上述字段
博客地址
代码下载
下面的mybatis-plus-fieldfill