国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇)

這篇具有很好參考價值的文章主要介紹了自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(攔截器實現(xiàn)篇)中提到過,寫了一個idea插件來輔助對Mapper接口中的方法添加自定義注解,這邊記錄一下插件的實現(xiàn)。

需求簡介

在上一篇中,定義了一個自定義注解對需要經(jīng)過where判斷的Mapper sql方法進行修飾。那么,現(xiàn)在想使用一個idea插件來輔助進行自定義注解的增加,需要做到以下幾點:

  1. 支持在接口名帶Mapper的編輯頁面中,右鍵菜單,顯示增加注解信息的選項
  2. 鼠標(biāo)移動到該選項,支持顯示可選的需要新增的注解名稱
  3. 點擊增加,對當(dāng)前Mapper中的所有方法增加對應(yīng)注解;同時,沒有import的文件中需要增加對應(yīng)的包導(dǎo)入。

具體實現(xiàn)

插件開發(fā)所需前置

第一點就是需要gradle進行打包,所以需要配置gradle項目和對應(yīng)的配置文件;第二點就是在Project Structure中,將SDK設(shè)置為IDEA的sdk,從而導(dǎo)入支持對idea界面和編輯內(nèi)容進行處理的api。idea大多數(shù)版本本身就會提供plugin開發(fā)專用的project,對應(yīng)的配置文件會在project模板中初始化,直接用就行。

插件配置文件

plugin.xml,放在reources的META-INF元數(shù)據(jù)文件夾下,自動進行插件基本信息的讀取:

<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
    <!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions. -->
    <id>com.huiluczp.checkAnnocationPlugin</id>

    <!-- Public plugin name should be written in Title Case.
         Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-name -->
    <name>CheckAnnocationPlugin</name>

    <!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. -->
    <vendor email="970921331@qq.com" url="https://www.huiluczp.com">huiluczP</vendor>

    <!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.
         Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.
         Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description -->
    <description>Simple annotation complete plugin used for mybatis mapping interface.</description>

    <!-- Product and plugin compatibility requirements.
         Read more: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html -->
    <depends>com.intellij.modules.platform</depends>
    <depends>com.intellij.modules.lang</depends>
    <depends>com.intellij.modules.java</depends>

    <!-- Extension points defined by the plugin.
         Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html -->
    <extensions defaultExtensionNs="com.intellij">

    </extensions>
    <actions>
        <group id="add_annotation_group" text="Add Self Annotation" popup="true">
            <!-- EditorPopupMenu是文件中右鍵會顯示的菜單 -->
            <add-to-group group-id="EditorPopupMenu" anchor="last"/>
            <action id="plugin.demoAction" class="com.huiluczp.checkannotationplugin.AnnotationAdditionAction" text="@WhereConditionCheck"
                    description="com.huiluczP.annotation.WhereConditionCheck">
            </action>
        </group>
    </actions>
</idea-plugin>

對插件功能實現(xiàn)來說,主要需要關(guān)注的是actions部分,其中,設(shè)置了一個名為add_annotation_group的菜單組,在這個標(biāo)簽中,使用add-to-group標(biāo)簽將其插入EditorPopupMenu中,也就是右鍵展開菜單。最后,在我們定義的菜單組中,增加一個action,也就是點擊后會進行對應(yīng)功能處理的單元,在class中設(shè)置具體的實現(xiàn)類,并用text設(shè)置需要顯示的信息。

功能類實現(xiàn)

將所有功能都塞到了AnnotationAdditionAction類中。

public class AnnotationAdditionAction extends AnAction {

    private Project project;
    private Editor editor;
    private String annotationStr;
    private AnActionEvent event;
    private String fullAnnotationStr;

    @Override
    // 主方法,增加對應(yīng)的注解信息
    public void actionPerformed(AnActionEvent event) {
        project = event.getData(PlatformDataKeys.PROJECT);
        editor = event.getRequiredData(CommonDataKeys.EDITOR);

        // 獲取注解名稱
        annotationStr = event.getPresentation().getText();
        fullAnnotationStr = event.getPresentation().getDescription();
        // 獲取
        // 獲取所有類
        PsiClass[] psiClasses = getAllClasses(event);

        // 對類中所有滿足條件的類增加Annotation
        for(PsiClass psiClass:psiClasses){
            // 滿足條件
            List<String> methodNames = new ArrayList<>();
            if(checkMapperInterface(psiClass)) {
                PsiMethod[] psiMethods = psiClass.getMethods();
                for (PsiMethod psiMethod : psiMethods) {
                    PsiAnnotation[] psiAnnotations = psiMethod.getAnnotations();
                    boolean isExist = false;
                    System.out.println(psiMethod.getName());
                    for (PsiAnnotation psiAnnotation : psiAnnotations) {
                        // 注解已存在
                        if (psiAnnotation.getText().equals(annotationStr)){
                            isExist = true;
                            break;
                        }
                    }
                    // 不存在,增加信息
                    if(!isExist){
                        System.out.println("add annotation "+annotationStr + ", method:" + psiMethod.getName());
                        methodNames.add(psiMethod.getName());
                    }
                }
            }
            // 創(chuàng)建線程進行編輯器內(nèi)容的修改
            // todo 考慮同名,還需要考慮對方法的參數(shù)判斷,有空再說吧
            WriteCommandAction.runWriteCommandAction(project, new TextChangeRunnable(methodNames, event));
        }
    }

實現(xiàn)類需要繼承AnAction抽象類,并通過actionPerformed方法來執(zhí)行具體的操作邏輯。通過event對象,可以獲取idea定義的project項目信息和editor當(dāng)前編輯窗口的信息。通過獲取當(dāng)前窗口的類信息,并編輯對應(yīng)文本,最終實現(xiàn)對所有滿足條件的方法增加自定義注解的功能。

    // 獲取對應(yīng)的method 并插入字符串
    class TextChangeRunnable implements Runnable{

        private final List<String> methodNames;
        private final AnActionEvent event;

        public TextChangeRunnable(List<String> methodNames, AnActionEvent event) {
            this.methodNames = methodNames;
            this.event = event;
        }

        @Override
        public void run() {
            String textNow = editor.getDocument().getText();
            StringBuilder result = new StringBuilder();
            // 考慮import,不存在則增加import信息
            PsiImportList psiImportList = getImportList(event);
            if(!psiImportList.getText().contains(fullAnnotationStr)){
                result.append("import ").append(fullAnnotationStr).append(";\n");
            }

            // 對所有的方法進行定位,增加注解
            // 粗暴一點,直接找到public的位置,前面增加注解+\n
            String[] strList = textNow.split("\n");
            for(String s:strList){
                boolean has = false;
                for(String methodName:methodNames) {
                    if (s.contains(methodName)){
                        has = true;
                        break;
                    }
                }
                if(has){
                    // 獲取當(dāng)前行的縮進
                    int offSet = calculateBlank(s);
                    result.append(" ".repeat(Math.max(0, offSet)));
                    result.append(annotationStr).append("\n");
                }
                result.append(s).append("\n");
            }
            editor.getDocument().setText(result);
        }

        // 找到字符串第一個非空字符前空格數(shù)量
        private int calculateBlank(String str){
            int length = str.length();
            int index = 0;
            while(index < length && str.charAt(index) == ' '){
                index ++;
            }
            if(index >= length)
                return -1;
            return index;
        }
    }

需要注意的是,在插件中對文本進行編輯,需要新建線程進行處理。TextChangeRunnable線程類對當(dāng)前編輯的每一行進行分析,保留對應(yīng)的縮進信息并增加public方法的自定義注解修飾。同時,判斷import包信息,增加對應(yīng)注解的import。

    @Override
    // 當(dāng)文件為接口,且名稱中包含Mapper信息時,才顯示對應(yīng)的右鍵菜單
    public void update(@NotNull AnActionEvent event) {
        super.update(event);
        Presentation presentation = event.getPresentation();
        PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
        presentation.setEnabledAndVisible(false); // 默認不可用
        if(psiFile != null){
            VirtualFile virtualFile = psiFile.getVirtualFile();
            FileType fileType = virtualFile.getFileType();
            // 首先滿足為JAVA文件
            if(fileType.getName().equals("JAVA")){
                // 獲取當(dāng)前文件中的所有類信息
                PsiClass[] psiClasses = getAllClasses(event);
                // 只允許存在一個接口類
                if(psiClasses.length!=1)
                    return;
                for(PsiClass psiClass:psiClasses){
                    // 其中包含Mapper接口即可
                    boolean isOk = checkMapperInterface(psiClass);
                    if(isOk){
                        presentation.setEnabledAndVisible(true);
                        break;
                    }
                }
            }
        }
    }

重寫update方法,當(dāng)前右鍵菜單顯示時,判斷是否為接口名帶Mapper的情況,若不是則進行自定義注解增加功能的隱藏。

    // 獲取當(dāng)前文件中所有類
    private PsiClass[] getAllClasses(AnActionEvent event){
        PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
        assert psiFile != null;
        FileASTNode node = psiFile.getNode();
        PsiElement psi = node.getPsi();
        PsiJavaFile pp = (PsiJavaFile) psi;
        return pp.getClasses();
    }

    // 獲取所有import信息
    private PsiImportList getImportList(AnActionEvent event){
        PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
        assert psiFile != null;
        FileASTNode node = psiFile.getNode();
        PsiElement psi = node.getPsi();
        PsiJavaFile pp = (PsiJavaFile) psi;
        return pp.getImportList();
    }

    // 判斷是否為名稱Mapper結(jié)尾的接口
    private boolean checkMapperInterface(PsiClass psiClass){
        if(psiClass == null)
            return false;
        if(!psiClass.isInterface())
            return false;
        String name = psiClass.getName();
        if(name == null)
            return false;
        return name.endsWith("Mapper");
    }

最后是幾個工具方法,通過psiFile來獲取對應(yīng)的psiJavaFile,從而得到對應(yīng)的類信息。

插件打包

因為使用了gradle,直接使用gradle命令進行打包。

gradlew build

之后會自動執(zhí)行完整的編譯和打包流程,最終會在/build/distributions文件夾下生成對應(yīng)的jar文件。
自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇),java,idea插件,java,intellij-idea
自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇),java,idea插件,java,intellij-idea
之后,在idea的settings中搜索plugins,點擊配置中的本地install選項,即可選擇并加載對應(yīng)的插件jar。
自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇),java,idea插件,java,intellij-idea

效果展示

創(chuàng)建一個簡單的UserMapper類。

public interface UserMapper {

    public String queryG();

    public String queryKKP();
}

在編輯頁面上右鍵顯示菜單,點擊我們之前設(shè)置的新按鈕增加自定義注解信息,增加成功。
自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇),java,idea插件,java,intellij-idea

自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇),java,idea插件,java,intellij-idea

總結(jié)

這次主要是記錄了下簡單的idea插件開發(fā)過程,idea的sdk以編輯頁面為基礎(chǔ)提供了PSI api來對當(dāng)前頁面與整體項目的展示進行修改,還是挺方便的。配置文件對action展示的位置進行編輯,感覺和傳統(tǒng)的gui開發(fā)差不多。
對現(xiàn)在這個插件,感覺還可以拓展一下編輯界面,輸進其他想增加的注解類型和展示邏輯,有空再拓展吧。文章來源地址http://www.zghlxwxcb.cn/news/detail-816882.html

到了這里,關(guān)于自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(自定義注解填充插件篇)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 防重復(fù)提交:自定義注解 + 攔截器(HandlerInterceptor)

    防重復(fù)提交:自定義注解 + 攔截器(HandlerInterceptor) 一、思路: 1、首先自定義注解; 2、創(chuàng)建攔截器實現(xiàn)類(自定義類名稱),攔截器(HandlerInterceptor); 3、創(chuàng)建類:配置攔截器路徑(攔截URL規(guī)則); 二、代碼示例: 1、首先自定義注解; 2、創(chuàng)建攔截器實現(xiàn)類(自定義類名

    2024年02月10日
    瀏覽(26)
  • Springboot 自定義 Mybatis攔截器,實現(xiàn) 動態(tài)查詢條件SQL自動組裝拼接(玩具)

    Springboot 自定義 Mybatis攔截器,實現(xiàn) 動態(tài)查詢條件SQL自動組裝拼接(玩具)

    ps:最近在參與3100保衛(wèi)戰(zhàn),戰(zhàn)況很激烈,剛剛打完仗,來更新一下之前寫了一半的博客。 該篇針對日常寫查詢的時候,那些動態(tài)條件sql 做個簡單的封裝,自動生成(拋磚引玉,搞個小玩具,不喜勿噴)。 來看看我們平時寫那些查詢,基本上都要寫的一些動態(tài)sql: ? 一個字段

    2024年02月12日
    瀏覽(30)
  • SpringCloud微服務(wù)實戰(zhàn)——搭建企業(yè)級開發(fā)框架:微服務(wù)安全加固—自定義Gateway攔截器實現(xiàn)防止SQL注入/XSS攻擊

    ?SQL注入是常見的系統(tǒng)安全問題之一,用戶通過特定方式向系統(tǒng)發(fā)送SQL腳本,可直接自定義操作系統(tǒng)數(shù)據(jù)庫,如果系統(tǒng)沒有對SQL注入進行攔截,那么用戶甚至可以直接對數(shù)據(jù)庫進行增刪改查等操作。 ??XSS全稱為Cross Site Script跨站點腳本攻擊,和SQL注入類似,都是通過特定方

    2024年02月03日
    瀏覽(25)
  • 自定義攔截器實現(xiàn)

    自定義攔截器實現(xiàn)

    在 Spring MVC 框架中, 攔截器作為一種機制, 用于對請求進行攔截. 攔截器可以在請求進入處理器之前、處理器返回處理之后、視圖渲染之前等各個環(huán)節(jié)進行攔截. 攔截器通常用于實現(xiàn)一下功能 : 鑒權(quán)和身份認證 日志記錄和統(tǒng)計 請求參數(shù)和校驗和過濾 緩存和性能優(yōu)化 路徑重定向

    2024年02月09日
    瀏覽(27)
  • SpringBoot Redis 注解 攔截器來實現(xiàn)接口冪等性校驗

    冪等性,?通俗的說就是一個接口,?多次發(fā)起同一個請求,?必須保證操作只能執(zhí)行一次 比如:訂單接口,?不能多次創(chuàng)建訂單 支付接口,?重復(fù)支付同一筆訂單只能扣一次錢 支付寶回調(diào)接口,?可能會多次回調(diào),?必須處理重復(fù)回調(diào) 普通表單提交接口,?因為網(wǎng)絡(luò)超時等原因多次點擊提

    2024年01月19日
    瀏覽(31)
  • Spring Boot入門(23):記錄接口日志再也不難!用AOP和自定義注解給Spring Boot加上日志攔截器!

    Spring Boot入門(23):記錄接口日志再也不難!用AOP和自定義注解給Spring Boot加上日志攔截器!

    ? ? ? ? 在上兩期中,我們著重介紹了如何集成使用 Logback?與?log4j2?日志框架的使用,今天我們講解的主題依舊跟日志有關(guān),不過不是使用何種開源框架,而是自己動手造。 ? ? ? ? Spring的核心之一AOP;AOP翻譯過來叫面向切面編程, 核心就是這個切面. 切面表示從業(yè)務(wù)邏輯中

    2024年02月11日
    瀏覽(25)
  • MybatisPlusInterceptor實現(xiàn)sql攔截器(超詳細)

    MybatisPlusInterceptor實現(xiàn)sql攔截器(超詳細)

    1 . 導(dǎo)入pom 2 . 配置下MybatisPlus的yml 3 . 實體類 4 .? DTO 5 . MybatisPlus的config 6 . controller 7 . 測試 ?成功實現(xiàn)sql攔截并進行拼接

    2024年02月11日
    瀏覽(15)
  • 利用Mybatis攔截器實現(xiàn)自定義的ID增長器

    利用Mybatis攔截器實現(xiàn)自定義的ID增長器

    原生的Mybatis框架是沒有ID自增器,但例如國產(chǎn)的Mybatis Plus卻是支持,不過,Mybatis Plus卻是缺少了自定屬性的填充;例如:我們需要自定義填充一些屬性,updateDate、createDate等,這時Mybatis Plus自帶的ID自增器就無法滿足需求;這種時候我們就需要自定義的ID增加器,可以自定義

    2024年02月19日
    瀏覽(26)
  • Mybatis攔截器注解@Intercepts與@Signature注解屬性說明

    可能有些新手使用mybatis攔截器的時候可能沒太懂@Signature注解中type,method,args的用法 首先mybatis攔截器可以攔截如下4中類型 Executor sql的內(nèi)部執(zhí)行器 ParameterHandler 攔截參數(shù)的處理 StatementHandler 攔截sql的構(gòu)建 ResultSetHandler 攔截結(jié)果的處理 type:就是指定攔截器類型(ParameterHandl

    2024年02月05日
    瀏覽(27)
  • 【SpringMVC】JSR 303與攔截器注解使用

    ? ?JSR 303,它是Java EE(現(xiàn)在稱為Jakarta EE)規(guī)范中的一部分。JSR 303定義了一種用于驗證Java對象的標(biāo)準(zhǔn)規(guī)范,也稱為Bean驗證。 ? ? ? ? Bean驗證是一種用于驗證對象屬性的框架,它可以確保對象符合特定的規(guī)則和約束。這些規(guī)則可以包括字段的非空性、長度限制、格式驗證等。

    2024年02月07日
    瀏覽(33)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包