SpringBoot整合freemarker實現(xiàn)代碼生成器
一、介紹
在實際的軟件項目開發(fā)過程中,我可以很負責任的跟大家說,如果你真的實際寫代碼的時間超過5年,你對增刪改查這類簡單的功能需求開發(fā),可以說已經完全寫吐了,至少我就是這種類型的。
但是呢,不可否認,絕大多數(shù)的軟件功能,向下追隨到最基本的單元,也基本都是單表的增、刪、改、查!
只是隨著用戶需求不斷增多,原來可能一個張單表就可以搞定的事情,現(xiàn)在可能需要多張表,或者多個庫才能搞定,代碼層就像堆積木一樣,越堆越復雜。
我記得早期做項目的時候,項目每新加一張單表,我都需要在代碼層,按照MVC框架的思想,重新編寫一套CURD的代碼,寫完所有的基礎的增刪改查,至少需要20分鐘,手快的情況下,最快也要10分鐘。
假如某個新開發(fā)的功能,要新增10張表,按照這個時間計算,至少要100分鐘,仔細想想,其實你會發(fā)現(xiàn)大部分的時間都浪費在這些簡單而又重復的編程圈子中去了。
那有沒有一個辦法,將這些簡單的CURD代碼,全部都標準化、公共化呢?這樣我們的可以省下很多時間來投入業(yè)務場景的開發(fā)。
答案是肯定的,有!
我記得早期我最先接觸的是MybatisGenertor工具包,通過這個工具包,我們可以省去大部分的mybaits中xml文件的curd編寫工作。
還有我們所熟悉的JPA,里面有一套公共的持久層動態(tài)代理類,它可以自動根據(jù)名稱生成SQL語句,能為開發(fā)省下不少的事情。
但是我這個人比較懶,我想搞一個工具,從controller、service、entity 、dao層,全部的crud代碼,包括單元測試類,通過工具自動生成好。
像這樣的工具,現(xiàn)在網上也有不少,例如我們所熟悉的Mybatis-plus插件,它就可以做到這一點,也是非常好用。
但是有的公司就不喜歡它,原因也很簡單,里面的很多公共方法封裝的過于深入,而且很多crud的sql全部都是動態(tài)生成,你根本看不到。
總之啊就是一句,不在自己掌控之內的,很多程序員總是帶著各種疑慮~~
當然,還有一個明顯的疑慮,就是對微服務的開發(fā),不能全面支持,比如你項目采用的是SpringBoot +Dubbo組合來開發(fā),這個時候生成的controller,完全沒啥用處,而且還很雞肋。
因此在這種情況下,你得基于當前的項目軟件開發(fā)規(guī)則,自己開發(fā)一套代碼生成器,以滿足快速開發(fā)的需要。
下面我就簡單的介紹一下,如何自行開發(fā)一套代碼生成器,過程如下!
二、代碼實踐
其實開發(fā)一套代碼生成器,真沒大家想象中的那么復雜,其中用的最重要一項技術,就是利用模板來生成代碼,例如我們經常使用的模板引擎freemarker,它就可以幫助我們實現(xiàn)這一點。
2.1、首先我們添加 freemarker 依賴包
<dependency> ????<groupId>org.freemarker</groupId> ????<artifactId>freemarker</artifactId> ????<version>2.3.23</version> </dependency>
2.2、然后創(chuàng)建一個代碼模版
下面我們以動態(tài)創(chuàng)建實體類為例,編寫一個實體類的模板entity.java.ftl,其中${}里面定義的是動態(tài)變量。
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",?"張三");
????????//定義創(chuàng)建時間
????????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("文件創(chuàng)建成功");
????}
}
運行程序,輸出的文件結果如下!
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;
????}
}與預期的效果一致,成功生成!
以上就是生成代碼最核心的部分,首先編寫一套模板,把需要填充的信息全部定義成動態(tài)變量,然后在代碼中,通過map數(shù)據(jù)格式,使用freemarker進行填充!
例如小編我就是采用這種方式,首先把要通過工具生成的代碼,全部通過模板方式定義好。

然后通過連接數(shù)據(jù)庫的方式,把需要自動生成的表結構查詢出來,封裝成數(shù)據(jù)渲染參數(shù),最后傳入到freemarker中去,非常簡單、快速的生成與自己預期想要的代碼,所有單表的crud全部一步到位!
下面這個就是小編,基于當前項目定制開發(fā)的一款代碼生成器,項目采用SpringBoot + Dubbo框架開發(fā),沒有Controller層,截圖中所有的代碼全部都是采用代碼生成器生成的,直接通過單元測試就可以運行,開發(fā)的時候非???!

由于開發(fā)的代碼生成器工具,代碼有點過多,因此不便于通過文章分享給大家,有需要的朋友,可以訪問如下鏈接獲取:https://github.com/justdojava/springboot-example-generator
三、小結
代碼生成器,對于擅長以業(yè)務開發(fā)為主的程序員來說,絕對是一個巨大的福利,它能很明顯的減輕開發(fā)人員的工作量,并且提升開發(fā)效率,能騰出更多的時間專注業(yè)務開發(fā)。
實際上,目前網上已經有很多的成熟、穩(wěn)定的代碼生成器,mybatis-plus就是其中一個使用非常廣泛的代碼生成器,對于以單體web開發(fā)為主的項目,它完全滿足要求。
當然,如果當下你沒有合適的代碼生成器,不妨自己試試開發(fā)一款屬于自己的代碼生成器,同樣也可以加倍提升開發(fā)效率。
以上就是SpringBoot整合freemarker實現(xiàn)代碼生成器的詳細內容,更多關于SpringBoot freemarker代碼生成器的資料請關注腳本之家其它相關文章!
相關文章
JdbcTemplate操作數(shù)據(jù)庫的具體方法
這篇文章主要介紹了JdbcTemplate操作數(shù)據(jù)庫的具體操作方法,準備工作需要大家先導入相關的jar包,建個數(shù)據(jù)庫,具體操作方法跟隨小編一起看看吧2022-03-03

