一、自定義實現MyBatis-Plus逆向工程
多數據源的問題解決了,接下來開始進行實際開發時,你會發現,最麻煩的一件事情就是要創建與數據庫表對應的POJO了。這些沒什么難度,但是繁瑣的內容會占據大量的開發時間。比如一個PmsProducr對象,有三四十個屬性。這就需要開發一個龐大的POJO對象。相反,上層的CRUD操作則相當簡單。只需要繼承MyBatis-plus框架提供的BaseMapper接口即可。
@DS("goods")
public interface PmsProductMapper extends BaseMapper<PmsProduct> {
}
?標準的CRUD操作完全都不需要進行聲明,直接就可以拿來用。只需要補充一些復雜的SQL操作即可。接下來當然是希望能夠用程序快速自動的生成這些POJO類了,這樣可以節省大量的開發時間。
關于如何生成POJO類,你當然可以使用MyBatis的逆向工程或者MyBatis-plus的逆向工程,這些網上有大量的資料,我們這里就不多做介紹。但是,你會不會有一種感覺,這些通用的逆向工程雖然優秀,但是卻都太過復雜。他
們為了工具的通用性,做了很多對我們沒有用的封裝。你有沒有想過自己做一個簡單使用的逆向工程出來呢?做一些這樣的思考會讓你對枯燥的CRUD工作產生一些不一樣的想法。
其實你可以思考一下,需要根據數據庫的表創建出對應的POJO類,需要哪些信息? 其實要的信息并不多。表名、列名、列類型、主鍵信息。有這些就差不多了。而這些信息,其實都可以從最簡單的JDBC操作中獲取到。
public static void main(String[] args) throws Exception {//mysqlClass.forName("com.mysql.cj.jdbc.Driver")?Properties props = new Properties()?props.put("useInformationSchema", "true")? //mysql獲取表注釋需要加上這個屬性props.put("user", "root")?props.put("password", "root")?Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/genserver?serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true",props)?System.out.println("========映射表信息==============")?DatabaseMetaData meta = con.getMetaData()?ResultSet tables = meta.getTables("genserver", "%", "black_info", new String[]{"TABLE"})?while(tables.next()) {ResultSetMetaData metaData = tables.getMetaData()?System.out.println(metaData.getColumnCount())?for(int i = 1 ? i <= metaData.getColumnCount()? i ++) {System.out.println(metaData.getColumnName(i)+" ==>"+tables.getString(metaData.getColumnName(i)))?}System.out.println(tables.getString("TABLE_NAME")+" --->>>"+tables.getString("REMARKS"))?}System.out.println("========映射列信息==============")?ResultSet columns = meta.getColumns("genserver", "%", "black_info", "%")?while(columns.next()) {String columnName = columns.getString("COLUMN_NAME")?String columnType = columns.getString("TYPE_NAME")?int datasize = columns.getInt("COLUMN_SIZE")?int digits = columns.getInt("DECIMAL_DIGITS")?int nullable = columns.getInt("NULLABLE")?String remarks = columns.getString("REMARKS")?System.out.println(columnName+" "+columnType+" "+datasize+" "+digits+" "+nullable+" "+remarks)?}System.out.println("========映射主鍵信息==============")?ResultSet primaryKeys = meta.getPrimaryKeys("genserver", "%", "black_info")?while(primaryKeys.next()) {ResultSetMetaData metaData = primaryKeys.getMetaData()?System.out.println(metaData.getColumnCount())?for(int i = 1 ? i <= metaData.getColumnCount()? i ++) {System.out.println(metaData.getColumnName(i)+" ==>"+primaryKeys.getString(metaData.getColumnName(i)))?}}
}
接下來如何將這些信息拼湊成一個POJO呢?你可以使用一個StringBu?er,一點點拼接出POJO的完整代碼,再一次輸出到文件當中,這沒有問題。但是這樣顯然會比較麻煩,而且容易出錯。
MyBatis的逆向工程使用的就是這種方式。
二、使用Freemarker模板引擎實現一鍵開發模式
對于這種問題,其實可以用模版引擎來做。將代碼中靜態的部分寫到模版當中,然后將動態部分交由模版生成。最為常用的模版引擎就是freemarker了。大部分場景下,freemarker通常是用來生成靜態HTML頁面的。比如在我們的電商場景中,就實現了對產品單品頁的靜態化功能。
使用靜態化功能,需要你創建 %{user_home}\template\ftl\目錄下放置report.ftl模版文件,同時需要提前創建 %{user_home}\template\report目錄?
freemarker是一個基于模版和數據輸出文本的通用工具。只需要準備好動態的業務數據,以及基于FTL語言編寫的模版文件,就可以快生成靜態的文本。?
如果你對freemarker不是很了解,可以從這個示例中快速理解freemarker模版引擎。這個引擎上手非常簡單,對于有開發經驗的你,肯定沒什么問題。按照以下幾個步驟就可以快速上手freemarker了。
1、引入maven依賴
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version>
</dependency>
?2、構建后臺數據
public class FreemarkerTest {public static void main(String[] args) throws Exception {// 第一步:創建一個Configuration對象,直接new一個對象。構造方法的參數就是freemarker對于的版本號。Configuration configuration = new Configuration(Configuration.getVersion())?// 第二步:設置模板文件所在的路徑。configuration.setDirectoryForTemplateLoading(new File("D:\\ftl"))?// 第三步:設置模板文件使用的字符集。一般就是utf‐8.注意版本。新版本不需要// configuration.setDefaultEncoding("UTF‐8")?// 第四步:加載一個模板,創建一個模板對象。Template template = configuration.getTemplate("test.ftl")?// 第五步:創建一個模板使用的數據集,可以是pojo也可以是map。一般是Map。Map dataModel = new HashMap<>()?//向數據集中添加數據dataModel.put("hello", "圖靈學院電商VIP")?// 第六步:創建一個Writer對象,一般創建一FileWriter對象,指定生成的文件名。Writer out = new FileWriter(new File("D:\\ftl\\out\\test.html"))?// 第七步:調用模板對象的process方法輸出文件。template.process(dataModel, out)?// 第八步:關閉流。out.close()?}
}
3、編寫ftl模版文件
最簡單模版文件就長這樣
<h1>
${hello}
</h1>
執行完成后,就會將模版中的${hello}部分替換成 圖靈學院電商VIP
一個ftl模版文件,是由少數幾個動態標簽加上其他靜態的內容組成。動態標簽包含以下幾種:
-
普通參數
例如${hello} -
list標簽
<#list studentList as student>
student.id/{student.id}/student.id/
{studnet.name}
</#list> -
if條件標簽
<#if student_index % 2 == 0>
<#else>
</#if>
在if標簽中,還可以進行簡單的null值判斷
<#if a??>
a不為空時。。
<#else>
a為空時###
</#if>
-
日期標簽
當前日期:?
date?date當前時間:{date?date} 當前時間:date?date當前時間:
{date?time}
當前日期和時間:date?datetime自定義日期格式:{date?datetime} 自定義日期格式:date?datetime自定義日期格式:
{date?string("yyyyMM/dd HH:mm: ss")} -
包含標簽
<#include "hello.ftl"/>
接下來如果你發揮一些想象,freemarker既然可以生成html文件,那是不是可以用來生成java源文件呢?顯然是可以的。
?能夠自己生成POJO了,那是不是可以把Service、Mapper、Controller等等這些重復性的代碼一起生成呢?實際上,如果你有這種規范化的思想,你甚至可以將前臺頁面都一并生成了。減少大部分的復制粘貼的重復工作。
最后,有了這個示例后,再來理解MyBatis-plus的逆向工程就非常容易了。 引入對應的依賴.
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.0.5</version>
</dependency>
?之后進入引入的jar包中,就能看到,MyBatis-plus的逆向工程也是使用freemarker和velocity提供的模版完成的逆向工程。
vm是velocity框架的模版文件。velocity是和freemarker功能類似的一個模版引擎。
后續在設計秒殺場景時,也會使用freemarker自動生成前端商品單品頁,實現動態頁面靜態化。
然后,發揮一下你自己的想象力,你還可以給這樣簡單的CRUD項目還能添加哪些與眾不同的,實用的設計?比如,MyBatis-plus使用模板引擎生成了后端代碼, 那么,對于一些長得差不多的數據管理頁面,我們能不能也使用模板引擎,把前臺頁面到后端管理的全棧功能都一起開發出來呢?
三、結合CBoard報表工具實現拖拽式報表開發
當我們將前后端整合到一起之后,就可以繼續發揮想象力,給普通的CRUD工作帶來一些不一樣的樂趣。
CBoard是一款開源的拖拽式報表開發工具,前端使用的是和我們項目一樣的VUE技術。那么,可不可以做這樣的設想,把CBoard中最后展現報表的前端頁面挪用到我們的前端項目中,然后將后端請求通過Dubbo開放出來,這樣我們就可以用很小的代碼集成一套拖拽式的報表開發工具了。