摘要:原博地址本文介紹如何用編寫高度自定義的代碼生成器是一款優(yōu)秀的持久層框架,它支持定制化存儲過程以及高級映射。避免了幾乎所有的代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集。
原博地址https://laboo.top/2018/11/26/a-db/#more
本文介紹如何用Java編寫高度自定義的代碼生成器
MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射原生信息。
上面這一段話來自Mybatis官網(wǎng)的介紹, 初用Mybatis時感覺這個框架相比于JDBC優(yōu)雅多了, 用起來也如官網(wǎng)說的非常簡單。但是用了一段時間之后, 弊端就慢慢凸顯出來了
使用Mybatis時不得不為每個表創(chuàng)建一個Entity.java、Mapper.xml(Mapper可以融合入Dao中)、Dao.java,Service.java 層次很清晰, 但是太多重復(fù)性的工作了, 費時間且易于出錯
并且當(dāng)數(shù)據(jù)庫發(fā)生一點改動的時候... 苦不堪言
后來出現(xiàn)了自動生成代碼的插件, 但是總是不盡人意, 不能隨心所欲地控制, 畢竟每個人的需求都不一樣
本文就來介紹如何簡單的編寫一個自己的代碼生成器
項目源碼mybatis-generator
代碼實現(xiàn)實現(xiàn)的思路很簡單, 首先查詢數(shù)據(jù)庫的表結(jié)構(gòu), 得到列名, 列類型...等信息
創(chuàng)建文件模版, 將這些信息插入模版中, 最后打包模版進壓縮包導(dǎo)出
代碼實現(xiàn) 一共五個Java類
TableDO
ColumnDO
GeneratorMapper
GeneratorUtils
GeneratorService
首先來看兩個實體類
TableDO 和 ColumnDOTableDO 存放表名, 對于的類名, 以及列信息
完整類代碼 TableDO.java
public class TableDO { private String tableName; private Listcolumns; private String className; private String suffix; // get()... set()... }
ColumnDO 存放列名, 數(shù)據(jù)庫字段類型, 以及對應(yīng)Java中的屬性名和類型
完整類代碼 ColumnDO.java
public class ColumnDO { private String columnName; private String dataType; private String attrName; private String attrLowerName; private String attrType; // get()... set()... }GeneratorMapper
在GeneratorMapper 中, 我們通過表名查詢表自動的信息
完整類代碼 GeneratorMapper.java
@Mapper public interface GeneratorMapper { @Select("select column_name columnName, data_type dataType from information_schema.columns where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position") ListGeneratorUtilslistColumns(String tableName); }
在GeneratorUtils 中進行類信息與模版之間的轉(zhuǎn)換
完整類代碼 GeneratorUtils.java
將表信息放入Velocity模版的上下文中
Mapmap = new HashMap<>(); map.put("tableName", table.getTableName()); map.put("className", table.getClassName()); map.put("pathName", getPackageName().substring(getPackageName().lastIndexOf(".") + 1)); map.put("columns", table.getColumns()); map.put("package", getPackageName()); map.put("suffix", table.getSuffix()); Properties prop = new Properties(); prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(prop); VelocityContext context = new VelocityContext(map);
添加模版
Listtemplates = new ArrayList<>(); templates.add("mybatis/Model.java.vm"); templates.add("mybatis/Query.java.vm"); templates.add("mybatis/Dao.java.vm"); templates.add("mybatis/Mapper.xml.vm"); templates.add("mybatis/Service.java.vm");
編譯模版
StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, "UTF-8"); tpl.merge(context, sw);
Utils類完成了生成代碼的主要工作, 但是代碼也是比較簡單的
GeneratorService在Service 中注入Mapper 查詢列信息, 并用Utils生成代碼, 然后導(dǎo)出壓縮包
完整類代碼 GeneratorService.java
@Service public class GeneratorService { @Resource private GeneratorMapper generatorMapper; @Resource private Environment environment; public void generateZip(String[] tableNames, String zipPath) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(outputStream); for (String tableName : tableNames) { TableDO table = new TableDO(); table.setTableName(tableName); table.setColumns(generatorMapper.listColumns(tableName)); GeneratorUtils.generatorCode(table, zip,getConfig()); } IOUtils.closeQuietly(zip); FileOutputStream file = new FileOutputStream(zipPath); file.write(outputStream.toByteArray()); file.close(); } // getConfig ... }VM模版
自己寫代碼生成器的好處就是, 可以根據(jù)需求定制自己的模版, 下面是我的幾個模版可以供參考
Mapper.xml.vm
Dao.java.vm
Service.java.vm
Model.java.vm
Query.java.vm
生成的代碼是在commons-mybatis架構(gòu)下使用的
Dao.java.vmpackage ${package}.database.dao; import ${package}.database.model.${className}${suffix}; import org.apache.ibatis.annotations.Mapper; import org.laziji.commons.mybatis.dao.${suffix}Dao; @Mapper public interface ${className}Dao extends ${suffix}Dao<${className}${suffix}> { }...
其余模版
使用 配置文件在resources下創(chuàng)建application-${name}.yml文件, ${name}隨意, 例如: application-example.yml, 可創(chuàng)建多個
配置文件內(nèi)容如下, 填入數(shù)據(jù)庫配置, 以及生成代碼的包名, 源文件路徑
spring: datasource: url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxxx?characterEncoding=utf-8 username: xxxxxx password: xxxxxx generator: package: com.xxx.xxx resources: mapperTest
在test文件下創(chuàng)建測試類
@ActiveProfiles("example")中填入剛才配置文件名的name
tableNames需要生成的表, 可以多個
zipPath 代碼導(dǎo)出路徑
運行測試方法即可
package pg.laziji.generator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; import pg.laziji.generator.mybatis.GeneratorService; import javax.annotation.Resource; import java.io.IOException; @ActiveProfiles("example") @RunWith(SpringRunner.class) @SpringBootTest public class ExampleTest { @Resource private GeneratorService generatorService; @Test public void test() throws IOException { String[] tableNames = new String[]{"example_table1", "example_table2"}; String zipPath = "/home/code.zip"; generatorService.generateZip(tableNames,zipPath); } }
歡迎關(guān)注我的博客公眾號
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72444.html
摘要:通過插件更優(yōu)雅地生成和的樣板代碼通過插件不污染地實現(xiàn)優(yōu)雅分頁。使用步驟引入依賴,在或的配置中進行配置。提供語法提示自動補全錯誤提示導(dǎo)航功能。該插件提供了類似的功能,根據(jù)接口的方法名推斷含義,然后在中直接生成對應(yīng)的。 團隊使用Mybatis作為數(shù)據(jù)庫訪問框架。不同于Hibernate這種采用經(jīng)典面向?qū)ο笏枷朐O(shè)計的ORM框架,Mybatis是面向過程的,它只做了過程到SQL語句的映射。兩者...
摘要:一級緩存值得注意的地方默認(rèn)就是支持一級緩存的,并不需要我們配置和整合后進行代理開發(fā),不支持一級緩存,和整合,按照的模板去生成代理對象,模板中在最后統(tǒng)一關(guān)閉。總結(jié)的一級緩存是級別的。 前言 本文主要講解Mybatis的以下知識點: Mybatis緩存 一級緩存 二級緩存 與Ehcache整合 Mapper代理 使用Mapper代理就不用寫實現(xiàn)類了 逆向工程 自動生成代碼 ...
摘要:是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)之一,在應(yīng)用方面,是最好的,關(guān)系數(shù)據(jù)庫管理系統(tǒng)應(yīng)用軟件。是一種關(guān)系數(shù)據(jù)庫管理系統(tǒng),關(guān)系數(shù)據(jù)庫將數(shù)據(jù)保存在不同的表中,而不是將所有數(shù)據(jù)放在一個大倉庫內(nèi),這樣就增加了速度并提高了靈活性。 本章主要是對MyBatis-Plus的初步介紹,包括一些背景知識、環(huán)境搭建、初步使用等知識和例子。對于背景知識,主要包含對MyBatis-Plus的特性介紹、為什么使用MyB...
摘要:最終能和面試官聊的開心愉快投緣的叫面霸。能夠與很好的集成提供映射標(biāo)簽,支持對象與數(shù)據(jù)庫的字段關(guān)系映射提供對象關(guān)系映射標(biāo)簽,支持對象關(guān)系組件維護。使用可以有效的防止注入,提高系統(tǒng)安全性。 showImg(https://segmentfault.com/img/bVbsSlt?w=358&h=269); 一、概述 面試,難還是不難?取決于面試者的底蘊(氣場+技能)、心態(tài)和認(rèn)知及溝通技巧。...
摘要:得到用戶信息,將用戶信息存儲到一級緩存中。如果中間去執(zhí)行操作執(zhí)行插入更新刪除,則會清空中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。 基礎(chǔ): 1、 概念:Java當(dāng)中的一個持久層框架。2、 特點、優(yōu)勢:(1)把java代碼和SQL代碼做了一個完全分離。(2)良好支持復(fù)雜對象的映射(輸入映射、輸出映射)(3)使用動態(tài)SQL,可以預(yù)防SQL注入。3、 ...
閱讀 2745·2021-09-26 10:19
閱讀 2176·2021-09-24 10:27
閱讀 2553·2021-09-01 10:42
閱讀 2333·2019-08-29 16:09
閱讀 2514·2019-08-29 15:17
閱讀 1479·2019-08-29 15:09
閱讀 663·2019-08-29 11:14
閱讀 2340·2019-08-26 13:25