欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis-Plus實現(xiàn)公共字段自動填充的項目實踐

 更新時間:2023年07月18日 14:53:08   作者:我愛布朗熊  
本文主要介紹了Mybatis-Plus實現(xiàn)公共字段自動填充的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、公共字段自動填充

1.1 問題分析

比如說在新增用戶需要指定創(chuàng)建時間、創(chuàng)建人等字段,

修改用戶時需要指定修改時間、修改人等字段

這些字段屬于公共字段,也就是很多表中都有這些字段

這樣我們在以后寫起來非常的麻煩, 每次做操作都需要自己手動寫。但是對于Mybatis plus來說這些是小意思,它為我們提供了公共字段自動填充功能

1.2 實現(xiàn)思路及代碼編寫

Mybatis plus 公共字段自動填充,也就是在插入或者更新的時候為指定字段賦予指定的值,使用它的好處就是統(tǒng)一對這些字段進行處理,避免了代碼重復。

實現(xiàn)步驟:

1. 在實體類的屬性上加入@TableField注解,指定自動填充的策略

    @TableField(value ="create_time",fill = FieldFill.INSERT)    //插入時填充字段
    private LocalDateTime createTime;
    @TableField(value ="update_time",fill = FieldFill.INSERT_UPDATE)//插入和更新時填充字段
    private LocalDateTime updateTime;
    @TableField(value = "create_user",fill = FieldFill.INSERT)//插入時填充字段
    private Long createUser;
    @TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)//插入和更新時填充字段
    private Long updateUser;

其中FieldFill是一個枚舉類,如下所示:

2. 按照框架要求編寫元數(shù)據(jù)對象處理器,在此類中統(tǒng)一為公共字段賦值,此類需要實現(xiàn)MetaObjectHandler接口

package com.reggie_take_out.common;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
 * 元數(shù)據(jù)對象處理器
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * 執(zhí)行insert語句的時候執(zhí)行
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自動填充——insertFill");
//      自動填充
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
//      獲取session對象
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
    /**
     * 執(zhí)行update語句的時候執(zhí)行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自動填充——updateFill");
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}

二、 知識補充: ThreadLocal

2.1  使用背景

為什么要使用這個類?

比如我們要給updateUser與createUser字段設置值的時候,我們是通過HttpServletRequest對象獲取

 request.getSession().getAttribute("employee");

但是我們在寫公共字段自動填充的時候發(fā)現(xiàn)不能使用HttpServletRequest。

除此之外,將用戶id放入到HttpSession中也是獲取不到的,MyMetaObjectHandler類中是不能獲取HttpSession對象的,所以我們需要其他方式來進行獲取。

客戶端發(fā)送的每次Http請求,對應的服務端都會分配一個新的線程來處理,在處理過程中涉及到下面類中的方法都屬于同一個線程

1.LoginCheckFilter 的doFilter方法

2.EmployeeController的update方法

3.MyMetaObjectHandler的updateFill方法  

解決思路:

我們可以在LoginCheckFilter的doFilter方法中獲取當前登錄用戶id,并調(diào)用ThreadLocal的set方法來設置當前線程的線程局部變量的值(用戶id),然后再MyMetaObjectHandler的updateFill方法中調(diào)用ThreadLocal的get方法來獲取當前線程所對應的線程局部變量的值(用戶id)

2.2 ThreadLocal介紹

  • ThreadLocal并不是一個Thread,而是Thread的局部變量。
  • 當使用ThreadLocal維護變量時,ThreadLocal為每個使用該變量的線程提供獨立的變量副本,所以每一個線程都可以獨立地改變自己副本,而不會影響其他線程所對應的副本。
  • ThreadLocal為每個線程提供單獨一份存儲空間,具有線程隔離的效果,只有在線程內(nèi)才能獲取到對應的值,線程外則不能訪問。

2.2.1  設置當前線程的線程局部變量的值   public void set(T value)

具體代碼查看2.3.1 

2.2.2  返回當前線程所對應的線程  局部變量的值 public T get()

具體代碼查看2.3.1 

2.3  實現(xiàn)功能

2.3.1 基于ThreadLocal封裝BaseContext工具類

/**
 * 基于ThreadLocal封裝工具類,用戶保存和獲取當前登錄用戶id
 */
public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

2.3.2 在過濾器方法中調(diào)用BaseContext工具類設置當前登錄用戶id

/**
 * 檢查用戶是否已經(jīng)完成登錄
 * 過濾器與攔截器的區(qū)別:Filter對所有訪問進行增強(在Tomcat服務器進行配置),Interceptor僅針對SpringMVC的訪問進行增強
 */
@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")  //urlPatterns指定攔截哪些路徑
public class LoginCheckFilter implements Filter {
    //  此對象的作用:路徑匹配器,  匹配路徑時支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//      servletRequest向下強制類型轉(zhuǎn)換
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //1. 獲取本次請求的URI( URI:請求的資源路徑)
        String requestURI = request.getRequestURI();
        log.info("攔截到請求:{}", request.getRequestURI());
        // 定義不用處理的請求路徑
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };
        //2. 判斷本次請求是否需要處理(因為有些請求并不需要用戶登錄)
        boolean check = check(requestURI, urls);
        //3.如果不需要處理,則直接放行
        if (check) {
            log.info("本次請求{}不需要處理", request.getRequestURI());
            filterChain.doFilter(request, response);
            return;
        }
        //4.判斷登錄狀態(tài),如果已登錄,則直接放行.從session中獲取用戶,如果獲取到說明已經(jīng)登錄
        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;
        }
        //5.如果未登錄則返回未登錄結(jié)果
        log.info("資源路徑路徑:{},用戶未登錄{}", request.getRequestURI(), request.getSession().getAttribute("employee"));
//           通過輸出流的方式向客戶端響應數(shù)據(jù)   (為什么要返回這個NOTLOGIN?  因為前端需要這個來進行判定是否登錄)
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
//        filterChain.doFilter(request, response);  加上這個就無法實現(xiàn)
    }
    /**
     * 檢查本次請求是否需要放行
     *
     * @param requestURI 請求的資源路徑
     * @param urls       放過的路徑
     * @return true 放行
     */
    public boolean check(String requestURI, String[] urls) {
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) {
//           放行
                return true;
            }
        }
        return false;
    }
}

2.3.3 在MyMetaObjectHandler的方法中調(diào)用BaseContext工具類獲取登錄用戶id

package com.reggie_take_out.common;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
 * 元數(shù)據(jù)對象處理器
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * 執(zhí)行insert語句的時候執(zhí)行
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自動填充——insertFill");
//      自動填充
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
//      獲取session對象
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
    /**
     * 執(zhí)行update語句的時候執(zhí)行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自動填充——updateFill");
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}

到此這篇關(guān)于Mybatis-Plus實現(xiàn)公共字段自動填充的項目實踐的文章就介紹到這了,更多相關(guān)Mybatis-Plus 公共字段自動填充內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解JavaWeb中過濾器與監(jiān)聽器的應用

    深入理解JavaWeb中過濾器與監(jiān)聽器的應用

    這篇文章主要介紹了JavaWeb中過濾器與監(jiān)聽器的應用,過濾器能夠?qū)ζヅ涞恼埱蟮竭_目標之前或返回響應之后增加一些處理代碼,監(jiān)聽器是一個接口內(nèi)容由我們實現(xiàn),會在特定時間被調(diào)用,感興趣想要詳細了解可以參考下文
    2023-05-05
  • Java異常堆棧打印次數(shù)限制機制用法詳解

    Java異常堆棧打印次數(shù)限制機制用法詳解

    在Java開發(fā)中,異常處理是保證程序健壯性的重要手段,但當同一個異常被頻繁拋出時,日志可能會被大量重復的堆棧信息淹沒,影響問題排查效率,所以本文給大家介紹了Java異常堆棧打印次數(shù)限制機制的用法,需要的朋友可以參考下
    2025-04-04
  • mybatis集成到spring的方式詳解

    mybatis集成到spring的方式詳解

    這篇文章主要介紹了mybatis是如何集成到spring的,將mybatis集成到spring之后,就可以被spring的ioc容器托管,再也不用自己創(chuàng)建SqlSessionFactory?、打開SqlSession等操作,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • GraalVM?native-image編譯后quarkus的超音速啟動

    GraalVM?native-image編譯后quarkus的超音速啟動

    這篇文章主要介紹了經(jīng)過GraalVM?native-image編譯后的quarkus,來帶大家驗證一下號稱超音速亞原子的quarkus是否名副其實,有需要的朋友可以借鑒參考下,希望能夠有所包幫助
    2022-02-02
  • Java實現(xiàn)AOP功能的封裝與配置的小框架實例代碼

    Java實現(xiàn)AOP功能的封裝與配置的小框架實例代碼

    這篇文章主要介紹了Java實現(xiàn)AOP功能的封裝與配置的小框架實例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • Java 編程之IO流資料詳細整理

    Java 編程之IO流資料詳細整理

    這篇文章主要介紹了Java 編程之IO流資料詳細整理的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • DolphinScheduler容錯源碼分析之Worker

    DolphinScheduler容錯源碼分析之Worker

    這篇文章主要為大家介紹了DolphinScheduler容錯源碼分析之Worker,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 解決mybatis三表連接查詢數(shù)據(jù)重復的問題

    解決mybatis三表連接查詢數(shù)據(jù)重復的問題

    這篇文章主要介紹了解決mybatis三表連接查詢數(shù)據(jù)重復的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • 淺談Spring中@Import注解的作用和使用

    淺談Spring中@Import注解的作用和使用

    這篇文章主要介紹了淺談Spring中@Import注解的作用和使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • 解決SpringCloud Gateway配置自定義路由404的坑

    解決SpringCloud Gateway配置自定義路由404的坑

    這篇文章主要介紹了解決SpringCloud Gateway配置自定義路由404的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論