最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實(shí)現(xiàn)公共字段自動(dòng)填充的方法步驟

 更新時(shí)間:2024年11月17日 13:53:37   作者:Oneforlove_twoforjob  
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)公共字段自動(dòng)填充的方法步驟,文中通過代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下

問題引入

JavaEE開發(fā)的時(shí)候,新增字段,修改字段大都會(huì)涉及到創(chuàng)建時(shí)間(createTime),更改時(shí)間(updateTime),創(chuàng)建人(craeteUser),更改人(updateUser),如果每次都要自己去setter(),會(huì)比較麻煩,可以使用Spring的AOP,對(duì)于任意Insert,Update操作進(jìn)行增強(qiáng)

解決步驟

主要依賴

如果使用了springboot,那就只需要導(dǎo)入這一個(gè),這個(gè)框架對(duì)spring自帶的aop框架進(jìn)行了優(yōu)化封裝,更好用

事實(shí)上,還需要兩個(gè)依賴,spring-context和spring-aop,不過springboot自帶的有

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>
 

注釋代碼

給那些新增、修改功能中的設(shè)置時(shí)間、修改人的代碼部分注釋掉

自定義注解&使用

封裝數(shù)據(jù)庫操作類型

/**
 * 數(shù)據(jù)庫操作類型
 */
public enum OperationType {
 
    /**
     * 更新操作
     */
    UPDATE,
 
    /**
     * 插入操作
     */
    INSERT
 
}

自定義注解 

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    // 數(shù)據(jù)庫操作類型:UPDATE INSERT
    OperationType value();
}

給需要自動(dòng)填充的方法加上注解 

    /**
     * 新增員工
     * @param employee
     */
    @Insert("INSERT INTO employee" +
            "(name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user)" +
            "VALUES" +
            "(#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
    @AutoFill(value = OperationType.INSERT)
    void insert(Employee employee);
 
    /**
     * 修改員工信息
     * @param employee
     */
    @AutoFill(value = OperationType.UPDATE)
    void update(Employee employee);
 
    /**
     * 根據(jù)ID查詢員工
     * @param id
     * @return
     */
    @Select("SELECT * FROM employee WHERE id = #{id}")
    Employee getById(Long id);
 
    /**
     * 密碼修改
     * @param passwordEditDTO
     */
    @AutoFill(value = OperationType.UPDATE)
    @Update("UPDATE employee SET `password` = #{newPassword} WHERE `id` = #{empId} AND `password` = #{oldPassword}")
    void updatePwd(PasswordEditDTO passwordEditDTO);

通知類

@Slf4j
@Component
@Aspect
public class AutoFillAspect {
 
    /**
     * 切面 && 指定切入點(diǎn)
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}
 
    /**
     * 切面 && 此方法(autoFill()) 在切入點(diǎn)之前執(zhí)行
     * @param joinPoint
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) {
        log.info("開始進(jìn)行公共字段自動(dòng)填充...");
 
        // 拿到當(dāng)前被攔截的方法上的數(shù)據(jù)庫操作類型
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();// 拿到實(shí)現(xiàn)類的簽名信息,不過我們只需要方法的簽名信息,強(qiáng)轉(zhuǎn)成MethodSignature
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);// 獲得簽名對(duì)象的注解對(duì)象
        OperationType operationType = autoFill.value(); // 拿到數(shù)據(jù)庫操作類型
 
        // 拿到當(dāng)前被攔截方法的方法參數(shù)(新增、更改方法的參數(shù)一般都是實(shí)體類)
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0){ // 防止null,防止空參
            return;
        }
 
        Object entity = args[0]; // 這一行就要求,以后的新增、更改方法參數(shù),實(shí)體類必須寫在首形參位置
 
        // 需填充的數(shù)據(jù)
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();
 
        // 根據(jù)當(dāng)前不同的操作類型,使用反射為對(duì)應(yīng)的屬性賦值
        if (operationType == OperationType.INSERT) {
            // 為4個(gè)公共字段賦值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
 
                // 通過反射給對(duì)象屬性賦值
                setCreateTime.invoke(entity, now);
                setUpdateTime.invoke(entity, now);
                setCreateUser.invoke(entity, currentId);
                setUpdateUser.invoke(entity, currentId);
 
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (operationType == OperationType.UPDATE) {
            // 為2個(gè)公共字段賦值
            try {
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
 
                // 通過反射給對(duì)象屬性賦值
                setUpdateTime.invoke(entity, now);
                setUpdateUser.invoke(entity, currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
 
        }
    }
}

依賴相關(guān)類

公共字段自動(dòng)填充相關(guān)常量

/**
 * 公共字段自動(dòng)填充相關(guān)常量
 */
public class AutoFillConstant {
    /**
     * 實(shí)體類中的方法名稱
     */
    public static final String SET_CREATE_TIME = "setCreateTime";
    public static final String SET_UPDATE_TIME = "setUpdateTime";
    public static final String SET_CREATE_USER = "setCreateUser";
    public static final String SET_UPDATE_USER = "setUpdateUser";
}

線程空間上下文

public class BaseContext {
 
    public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
 
    public static void setCurrentId(Long id) {
        threadLocal.set(id);
    }
 
    public static Long getCurrentId() {
        return threadLocal.get();
    }
 
    public static void removeCurrentId() {
        threadLocal.remove();
    }
 
}

啟動(dòng)類加上注解@EnableAspectJAutoProxy

@SpringBootApplication
@EnableTransactionManagement //開啟注解方式的事務(wù)管理
@EnableAspectJAutoProxy // 開啟注解方式的AOP
@Slf4j
public class SkyApplication {
    public static void main(String[] args) {
        SpringApplication.run(SkyApplication.class, args);
        log.info("server started");
    }
}

在這段代碼中,joinPoint 是 Spring AOP 中的一個(gè)概念,表示連接點(diǎn),即在程序執(zhí)行過程中切入的某個(gè)點(diǎn)。Signature 則是 Signature 接口的實(shí)現(xiàn)類之一,用于表示連接點(diǎn)的簽名信息,包括方法名、參數(shù)列表等。

具體來說,這段代碼的含義是從 joinPoint 中獲取連接點(diǎn)的簽名信息,并將其強(qiáng)制轉(zhuǎn)換為 MethodSignature 類型。然后可以通過 signature 對(duì)象獲取連接點(diǎn)(被代理方法)的詳細(xì)信息,比如方法名、參數(shù)類型等。

例如,可以通過 signature.getMethod().getName() 獲取連接點(diǎn)方法的名稱,通過 signature.getParameterTypes() 獲取連接點(diǎn)方法的參數(shù)類型數(shù)組等。

需要注意的是,在實(shí)際應(yīng)用中,我們使用這段代碼時(shí)需要確保 joinPoint 真正代表了一個(gè)方法連接點(diǎn),否則在強(qiáng)制轉(zhuǎn)換為 MethodSignature 時(shí)可能會(huì)拋出類型轉(zhuǎn)換異常。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)公共字段自動(dòng)填充的方法步驟的文章就介紹到這了,更多相關(guān)SpringBoot公共字段自動(dòng)填充內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Jenkins系統(tǒng)如何進(jìn)行數(shù)據(jù)備份

    Jenkins系統(tǒng)如何進(jìn)行數(shù)據(jù)備份

    隨著我們的長(zhǎng)期使用,Jenkins系統(tǒng)中的內(nèi)容會(huì)越來越多,特別是一些配置相關(guān)的東西,不能有任何丟失。這個(gè)時(shí)候我們就需要定期備份我們的Jenkins系統(tǒng),避免一些誤操作不小心刪除了某些重要文件,本文就將介紹下Jenkins系統(tǒng)如何進(jìn)行數(shù)據(jù)備份
    2021-06-06
  • Java之Algorithm_analysis案例詳解

    Java之Algorithm_analysis案例詳解

    這篇文章主要介紹了Java之Algorithm_analysis案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Java類中static{}的具體使用

    Java類中static{}的具體使用

    static{}(即static塊),會(huì)在類被加載的時(shí)候執(zhí)行且僅會(huì)被執(zhí)行一次,一般用來初始化靜態(tài)變量和調(diào)用靜態(tài)方法,本文主要介紹了Java類中static{}的具體使用,感興趣的可以了解一下
    2024-07-07
  • 一篇文章帶你了解一些Java反射的學(xué)習(xí)記錄

    一篇文章帶你了解一些Java反射的學(xué)習(xí)記錄

    java反射機(jī)制是一個(gè)很好用的東西,用它可以解決很多死的東西,因?yàn)榉瓷錂C(jī)制的靈活行很大,有了他,我們就不要花太多的時(shí)間來寫操做數(shù)據(jù)庫的代碼了,這個(gè)可以很大的減少開發(fā)時(shí)間,而且代碼的可讀性好
    2021-09-09
  • mybatis條件語句中帶數(shù)組參數(shù)的處理

    mybatis條件語句中帶數(shù)組參數(shù)的處理

    這篇文章主要介紹了mybatis條件語句中帶數(shù)組參數(shù)的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java利用反射實(shí)現(xiàn)動(dòng)態(tài)代理示例

    java利用反射實(shí)現(xiàn)動(dòng)態(tài)代理示例

    這篇文章主要介紹了java利用反射實(shí)現(xiàn)動(dòng)態(tài)代理示例,需要的朋友可以參考下
    2014-04-04
  • SpringBoot下獲取resources目錄下文件的常用方法

    SpringBoot下獲取resources目錄下文件的常用方法

    本文詳細(xì)介紹了SpringBoot獲取resources目錄下文件的常用方法,包括使用this.getClass()方法、ClassPathResource獲取以及hutool工具類ResourceUtil獲取,感興趣的可以了解一下
    2024-10-10
  • springboot2.x實(shí)現(xiàn)oauth2授權(quán)碼登陸的方法

    springboot2.x實(shí)現(xiàn)oauth2授權(quán)碼登陸的方法

    這篇文章主要介紹了springboot2.x實(shí)現(xiàn)oauth2授權(quán)碼登陸的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • springboot項(xiàng)目打包鏡像方式以及區(qū)分環(huán)境打包的方法

    springboot項(xiàng)目打包鏡像方式以及區(qū)分環(huán)境打包的方法

    本文主要介紹了springboot項(xiàng)目打包鏡像方式以及區(qū)分環(huán)境打包的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • java web實(shí)現(xiàn)自動(dòng)登錄功能

    java web實(shí)現(xiàn)自動(dòng)登錄功能

    這篇文章主要為大家詳細(xì)介紹了java web實(shí)現(xiàn)自動(dòng)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10

最新評(píng)論

龙山县| 云梦县| 新龙县| 新巴尔虎右旗| 天津市| 福清市| 运城市| 永和县| 绍兴市| 滨州市| 临泉县| 临城县| 大名县| 尉犁县| 留坝县| 确山县| 汾西县| 大方县| 江源县| 汽车| 留坝县| 南岸区| 山东| 柳江县| 伊金霍洛旗| 南和县| 上蔡县| 紫阳县| 浦城县| 古交市| 定远县| 思南县| 彰化市| 丹棱县| 集安市| 福州市| 习水县| 容城县| 河东区| 望奎县| 芦山县|