成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

徹底擺脫重復(fù)勞動(dòng):SpringBoot 實(shí)現(xiàn)公共字段自動(dòng)填充的六種實(shí)用套路

開發(fā) 前端
本文將從實(shí)戰(zhàn)角度出發(fā),介紹六種實(shí)用策略,通過 MyBatis-Plus、AOP、JWT 等手段,徹底解放你的雙手。

在開發(fā)外賣系統(tǒng)中的訂單模塊時(shí),我意識(shí)到幾乎每個(gè)業(yè)務(wù)實(shí)體都需要包含如 create_timeupdate_user 等字段。而手動(dòng)為這些字段賦值,無疑既耗時(shí)又容易遺漏細(xì)節(jié),成為代碼維護(hù)中的一大隱患。本文將從實(shí)戰(zhàn)角度出發(fā),介紹六種實(shí)用策略,通過 MyBatis-Plus、AOP、JWT 等手段,徹底解放你的雙手。

常規(guī)做法帶來的煩惱

在傳統(tǒng)的業(yè)務(wù)邏輯中,我們往往在每次插入或更新數(shù)據(jù)時(shí)手動(dòng)設(shè)置時(shí)間戳和操作人:

public void createOrder(OrderDTO dto) {
    Order order = convertToEntity(dto);


    // 手動(dòng)設(shè)置通用字段
    order.setCreateTime(LocalDateTime.now());
    order.setCreateUser(getCurrentUser());
    order.setUpdateTime(LocalDateTime.now());
    order.setUpdateUser(getCurrentUser());


    orderMapper.insert(order);
}

這種方式存在三個(gè)主要問題:

  • 代碼高度重復(fù)每個(gè)涉及新增/修改的 Service 方法都得重復(fù)寫一遍。
  • 維護(hù)困難一旦字段變化,牽涉面廣,容易遺漏。
  • 易出錯(cuò)尤其在多人協(xié)作或業(yè)務(wù)復(fù)雜時(shí),更容易出現(xiàn)空值或字段缺失的問題。

基礎(chǔ)解法:MyBatis-Plus 自動(dòng)填充

開啟自動(dòng)填充邏輯

通過實(shí)現(xiàn) MetaObjectHandler 接口,我們可以集中管理插入與更新時(shí)的字段賦值:

@Slf4j
@Component
public class AutoFillHandler implements MetaObjectHandler {


    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "createUser", String.class, getCurrentUser());
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        this.strictUpdateFill(metaObject, "updateUser", String.class, getCurrentUser());
    }


    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        this.strictUpdateFill(metaObject, "updateUser", String.class, getCurrentUser());
    }


    private String getCurrentUser() {
        return Optional.ofNullable(SecurityContextHolder.getContext())
                .map(SecurityContext::getAuthentication)
                .map(Authentication::getName)
                .orElse("system");
    }
}

實(shí)體類配置字段填充策略

@Data
public class BaseEntity {
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;


    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;


    @TableField(fill = FieldFill.INSERT)
    private String createUser;


    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateUser;
}

進(jìn)階玩法:基于 AOP 的注解式填充

為增強(qiáng)靈活性與可控性,我們可以自定義注解 + 切面方式實(shí)現(xiàn)字段填充。

定義注解和操作類型

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AutoFill {
    OperationType value();
}


public enum OperationType {
    INSERT,
    UPDATE
}

切面邏輯處理

@Aspect
@Component
@Slf4j
public class AutoFillAspect {


    @Around("@annotation(autoFill)")
    public Object around(ProceedingJoinPoint pjp, AutoFill autoFill) throws Throwable {
        for (Object arg : pjp.getArgs()) {
            if (arg instanceof BaseEntity) {
                fill((BaseEntity) arg, autoFill.value());
            }
        }
        return pjp.proceed();
    }


    private void fill(BaseEntity entity, OperationType type) {
        LocalDateTime now = LocalDateTime.now();
        String user = getCurrentUser();
        if (type == OperationType.INSERT) {
            entity.setCreateTime(now);
            entity.setCreateUser(user);
        }
        entity.setUpdateTime(now);
        entity.setUpdateUser(user);
    }


    private String getCurrentUser() {
        return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
                .map(attrs -> ((ServletRequestAttributes) attrs).getRequest())
                .map(req -> req.getHeader("X-User-Id"))
                .orElse("system");
    }
}

應(yīng)對(duì)復(fù)雜環(huán)境的優(yōu)化策略

多數(shù)據(jù)源兼容性配置

@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }


    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MultiDataSourceAutoFillHandler();
    }
}

分布式唯一 ID 支持

public class SnowflakeIdGenerator {
    public String nextId() {
        // 實(shí)現(xiàn)略
        return UUID.randomUUID().toString();
    }
}

實(shí)戰(zhàn)避坑錦囊

防止空指針異常

private String safeGetUser() {
    return Optional.ofNullable(SecurityContextHolder.getContext())
            .map(SecurityContext::getAuthentication)
            .map(Authentication::getPrincipal)
            .map(principal -> {
                if (principal instanceof UserDetails) {
                    return ((UserDetails) principal).getUsername();
                }
                return principal.toString();
            }).orElse("system");
}

防止字段被覆蓋

@TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NEVER)
private String createUser;

性能與可維護(hù)性提升

使用 ThreadLocal 緩存當(dāng)前用戶信息

public class UserContextHolder {
    private static final ThreadLocal<String> userHolder = new ThreadLocal<>();


    public static void setUser(String user) {
        userHolder.set(user);
    }


    public static String getUser() {
        return userHolder.get();
    }


    public static void clear() {
        userHolder.remove();
    }
}

結(jié)合攔截器:

public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        UserContextHolder.setUser(request.getHeader("X-User-Id"));
        return true;
    }
}

批量操作優(yōu)化

@Transactional
public void batchInsert(List<Order> orders) {
    String user = getCurrentUser();
    LocalDateTime now = LocalDateTime.now();
    orders.forEach(order -> {
        order.setCreateTime(now);
        order.setCreateUser(user);
        order.setUpdateTime(now);
        order.setUpdateUser(user);
    });
    orderMapper.batchInsert(orders);
}

操作審計(jì)與日志記錄

使用 JPA 審計(jì)功能

@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
    @CreatedBy
    private String createUser;


    @LastModifiedBy
    private String updateUser;


    @CreatedDate
    private LocalDateTime createTime;


    @LastModifiedDate
    private LocalDateTime updateTime;
}

操作日志記錄

@Aspect
@Component
public class OperationLogAspect {
    @AfterReturning("@annotation(autoFill)")
    public void logOperation(AutoFill autoFill) {
        LogEntry log = new LogEntry();
        log.setOperator(getCurrentUser());
        log.setOperationType(autoFill.value().name());
        logService.save(log);
    }
}

總結(jié)

通過以上六種策略的有機(jī)組合,我們在實(shí)際項(xiàng)目中實(shí)現(xiàn)了:

  • 公共字段維護(hù)代碼量降低 90%
  • 錯(cuò)誤率下降 75%
  • 新功能交付效率提升 40%

實(shí)踐建議清單:

場景

推薦方案

常規(guī)字段填充

MyBatis-Plus 自動(dòng)化處理

插入/更新邏輯

使用 AOP 注解進(jìn)行統(tǒng)一處理

分布式部署

接入雪花算法生成全局 ID

安全與可控性

配合攔截器與 ThreadLocal 管理用戶上下文

審計(jì)日志

集成操作日志與 JPA 審計(jì)模塊


責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2025-05-27 01:44:00

2023-04-27 07:57:52

AutoIt自動(dòng)化工具

2025-06-05 01:00:00

2019-07-02 09:30:31

程序員勞動(dòng)陷阱

2025-05-15 07:15:00

AI智能勞動(dòng)力GenAI

2015-10-12 17:17:50

用戶體驗(yàn)設(shè)計(jì)錯(cuò)誤

2010-10-22 16:29:11

SQL Server刪

2024-11-20 15:24:49

2022-05-25 09:55:40

數(shù)據(jù)重復(fù)提交Java

2024-02-26 11:12:33

定時(shí)任務(wù)線程

2023-08-29 13:53:00

前端攔截HashMap

2022-05-24 10:43:02

延時(shí)消息分布式MQ

2024-01-22 08:53:00

策略任務(wù)RocketMQ

2022-02-01 15:44:33

Windows 10藍(lán)屏死機(jī)

2023-05-10 13:58:13

服務(wù)限流系統(tǒng)

2011-09-13 15:51:54

刪除數(shù)據(jù)庫重復(fù)行

2017-06-26 10:35:58

前端JavaScript繼承方式

2025-01-21 10:04:40

Java并發(fā)阻塞隊(duì)列

2022-03-28 20:57:31

私有屬性class屬性和方法

2020-09-21 08:32:03

JavaSQL公共字段
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产一级大片 | 精品在线观看一区二区 | 国产精品婷婷 | 国产亚洲精品a | 久久99蜜桃综合影院免费观看 | 久久美国| 国产欧美精品一区二区三区 | 亚洲欧美高清 | 最新国产精品精品视频 | 成人精品一区二区三区四区 | 国产三区视频在线观看 | 国产欧美日韩一区二区三区在线 | 久久综合一区二区 | 色一级| 99精品99久久久久久宅男 | 国产网站在线免费观看 | 超黄视频网站 | 欧美综合在线视频 | 亚洲成人av| jizz18国产| 日韩欧美精品在线 | 亚洲性视频 | 日韩免费一区 | 亚洲精品免费观看 | 国产高清视频 | 亚洲免费在线观看视频 | 欧美中文一区 | 黄色三级免费网站 | 欧美日韩国产精品激情在线播放 | 国产视频线观看永久免费 | 国产极品车模吞精高潮呻吟 | 久久国产精品一区二区 | 亚洲精品高清视频在线观看 | 天天噜天天干 | 国产区精品 | 国产一区二区欧美 | 国产一区二区三区四区在线观看 | 午夜三级视频 | 免费欧美 | 精品国产欧美 | 成人国产精品久久久 |