首頁  >  文章  >  Java  >  SpringBoot怎麼整合freemarker實作程式碼產生器

SpringBoot怎麼整合freemarker實作程式碼產生器

WBOY
WBOY轉載
2023-05-10 20:37:101216瀏覽

    一、介紹

    在實際的軟體專案開發過程中,我可以很負責任的跟大家說,如果你真的實際寫程式碼的時間超過5年,你對增刪改查這類簡單的功能需求開發,可以說已經完全寫吐了,至少我就是這種類型的。

    但是呢,不可否認,絕大多數的軟體功能,向下追隨到最基本的單元,也基本上都是單表的增、刪、改、查!

    只是隨著用戶需求不斷增多,原來可能一個張單表就可以搞定的事情,現在可能需要多張表,或者多個庫才能搞定,代碼層就像堆積木一樣,越堆越複雜。

    我記得早期做專案的時候,專案每新加一張單表,我都需要在程式碼層,按照MVC框架的思想,重新寫一套CURD的程式碼,寫完所有的基礎的增刪改查,至少需要20分鐘,手快的情況下,最快也要10分鐘。

    假如某個新開發的功能,要新增10張表,按照這個時間計算,至少要100分鐘,仔細想想,其實你會發現大部分的時間都浪費在這些簡單而又重複的程式圈中去了。

    那有沒有一個辦法,將這些簡單的CURD程式碼,全部都標準化、公共化呢?這樣我們的可以省下很多時間來投入業務場景的開發。

    答案是肯定的,有!

    我記得早期我最先接觸的是MybatisGenertor工具包,透過這個工具包,我們可以省去大部分的mybaitsxml檔案的curd編寫工作。

    還有我們所熟悉的JPA,裡面有一套公共的持久層動態代理類,它可以自動根據名稱生成SQL語句,能為開發省下不少的事情。

    但是我這個人比較懶,我想搞一個工具,從controllerserviceentity dao層,全部的crud程式碼,包括單元測試類,透過工具自動生成好。

    像這樣的工具,現在網路上也有不少,例如我們所熟悉的Mybatis-plus插件,它就可以做到這一點,也是非常好用。

    但是有的公司就不喜歡它,原因也很簡單,裡面的許多公共方法封裝的過於深入,而且很多crudsql全部都是動態生成,你根本看不到。

    總之啊就是一句,不在自己掌控之內的,很多程式設計師總是帶著各種疑慮~~

    當然,還有一個明顯的疑慮,就是對微服務的開發,不能全面支持,例如你專案採用的是SpringBoot Dubbo組合來開發,這個時候生成的controller,完全沒啥用處,而且還很雞肋。

    因此在這種情況下,你得基於當前的專案軟體開發規則,自己開發一套程式碼產生器,以滿足快速開發的需要。

    下面我就簡單的介紹一下,如何自行開發一套程式碼產生器,流程如下!

    二、程式碼實踐

    其實開發一套程式碼產生器,真沒大家想像中的那麼複雜,其中用的最重要一項技術,就是利用模板來生成程式碼,例如我們經常使用的模板引擎freemarker,它可以幫助我們實現這一點。

    2.1、首先我們加入freemarker 依賴套件

    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.23</version>
    </dependency>

    2.2、然後建立一個程式碼模版

    下面我們以動態建立實體類別為例,寫一個實體類別的模板entity.java.ftl,其中${}裡面定義的是動態變數。

    package ${package};
    
    import java.io.Serializable;
    
    /**
     * <p>
     * ${tableComment}
     * </p>
     *
     * @author ${author}
     * @since ${date}
     */
    public class ${entityClass} implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
        <#--属性遍历-->
        <#list columns as pro>
    
        /**
         * ${pro.comment}
         */
        private ${pro.propertyType} ${pro.propertyName};
        </#list>
    
        <#--属性get||set方法-->
        <#list columns as pro>
        public ${pro.propertyType} get${pro.propertyName?cap_first}() {
            return this.${pro.propertyName};
        }
    
        public ${entityClass} set${pro.propertyName?cap_first}(${pro.propertyType} ${pro.propertyName}) {
            this.${pro.propertyName} = ${pro.propertyName};
            return this;
        }
        </#list>
    }

    2.3、最後產生目標程式碼

    最後我們基於freemarker寫一個測試類別!

    public class CodeGeneratorDemo {
    
        public static void main(String[] args) throws IOException, TemplateException {
            Map<String, Object> objectMap = new HashMap<>();
            //定义包路径
            objectMap.put("package", "com.example.test");
            //定义实体类
            objectMap.put("entityClass", "Student");
    
            //定义实体类属性
            List<Map<String, Object>> columns = new ArrayList<>();
            //姓名字段
            Map<String, Object> column1 = new HashMap<>();
            column1.put("propertyType", "String");
            column1.put("propertyName", "name");
            column1.put("comment", "姓名");
            columns.add(column1);
            //年龄字段
            Map<String, Object> column2 = new HashMap<>();
            column2.put("propertyType", "Integer");
            column2.put("propertyName", "age");
            column2.put("comment", "年龄");
            columns.add(column2);
    
            //定义类的属性
            objectMap.put("columns", columns);
            //定义作者
            objectMap.put("author", "张三");
            //定义创建时间
            objectMap.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            //定义类描述
            objectMap.put("tableComment", "学生信息");
    
            //生产目标代码
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
            configuration.setDefaultEncoding(Charset.forName("UTF-8").name());
            configuration.setClassForTemplateLoading(CodeGeneratorDemo.class, "/");
            Template template = configuration.getTemplate("/templates/entity.java.ftl");
            FileOutputStream fileOutputStream = new FileOutputStream(new File("../src/main/java/com/example/generator/Student.java"));
            template.process(objectMap, new OutputStreamWriter(fileOutputStream, Charset.forName("UTF-8").name()));
            fileOutputStream.close();
            System.out.println("文件创建成功");
    
        }
    }

    運行程序,輸出的檔案結果如下!

    package com.example.test;
    
    import java.io.Serializable;
    
    /**
     * <p>
     * 学生信息
     * </p>
     *
     * @author 张三
     * @since 2021-08-22
     */
    public class Student implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
        public String getName() {
            return this.name;
        }
    
        public Student setName(String name) {
            this.name = name;
            return this;
        }
        public Integer getAge() {
            return this.age;
        }
    
        public Student setAge(Integer age) {
            this.age = age;
            return this;
        }
    }

    與預期的效果一致,成功產生!

    例如小編我就是採用這種方式,首先把要透過工具產生的程式碼,全部透過模板方式定義好。

    SpringBoot怎麼整合freemarker實作程式碼產生器

    然後透過連接資料庫的方式,把需要自動產生的表格結構查詢出來,封裝成資料渲染參數,最後傳入到freemarker中去,非常簡單、快速的生成與自己預期想要的程式碼,所有單表的crud全部一步到位!

    下面這個是小編,基於當前專案客製開發的一款程式碼產生器,專案採用SpringBoot Dubbo框架開發,沒有Controller層,截圖中所有的程式碼全部都是採用程式碼產生器產生的,直接通過單元測試就可以運行,開發的時候非常快!

    SpringBoot怎麼整合freemarker實作程式碼產生器

    以上是SpringBoot怎麼整合freemarker實作程式碼產生器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除