EasyCode是基於IntelliJ IDEA開發的代碼生成插件,經過自定義生成模板能夠完成定製化的 Mapper Service Controller 生成,結合數據庫 Comment還能夠實現從數據庫到 Swagger 的一鍵配置,很是的強大與方便,項目地址:EasyCode--碼雲 這裏推薦你們使用java
和通常的Idea插件安裝方式同樣,點擊 File -> Setting -> Plugins 搜索 EasyCode 點擊 Install 安裝便可,安裝以後須要重啓,固然若是是Idea最新的2019.3版本支持插件熱安裝就不須要重啓了。git
安裝以後須要使用Idea鏈接數據庫,在Idea的右側有個DataBase選項卡,點擊以後選擇對應的數據庫。這邊我使用的是 Mysql 數據庫程序員
配置好鏈接名稱,鏈接路徑,帳號密碼和數據庫測試鏈接,測試經過後點擊OK,就能夠成功的鏈接到數據庫,這裏Idea的數據庫圖形化界面作的也挺好的。web
一樣是 File -> Settings -> other Settings 選擇 EasyCode 或者直接搜索 EasyCode 進行編輯,首先鍵入做者名稱,這樣在生成的類上面就會加上你的名字,時間等信息。spring
此頁面是用來創建數據庫字段類型與Java變量類型關係的,其中已經預先定義好了不少對應關係,但對於 tinyint((\d+))? unsigned (無符號的byte)類型卻沒有進行預約義,若是不進行手動配置,在進行逆向生成的時候會將其映射成 Java Object 類型,因此須要咱們進行手動的添加關聯關係sql
這個頁面就是咱們主要須要配置的頁面了,咱們能夠本身新建一個模板組,也能夠直接在原來模板文件的基礎上進行修改。這裏我已經對原有的模板進行了自定義的修改,保留了 entity.java mapper.java mapper.xml service.java controller.java 去掉了原有的 dao serviceImpl.具體的模板內容以下,須要的朋友能夠直接複製修改。數據庫
固然也能夠點擊配置做者名稱頁面的導入模板按鈕,輸入對應的 Token 進行一鍵替換因爲token只能保持6個小時,因此我就不在這裏貼上了。apache
實體類模板改動以下json
##引入宏定義 $!define ##使用宏定義設置回調(保存位置與文件後綴) #save("/entity", ".java") ##使用宏定義設置包後綴 #setPackageSuffix("entity") ##使用全局變量實現默認包導入 $!autoImport import java.io.Serializable; import io.swagger.annotations.*; import lombok.Data; ##使用宏定義實現類註釋信息 #tableComment("實體類") @Data @ApiModel("$tableInfo.comment") public class $!{tableInfo.name} implements Serializable { private static final long serialVersionUID = $!tool.serial(); #foreach($column in $tableInfo.fullColumn) #if(${column.comment})/** * ${column.comment} */#end @ApiModelProperty("$column.comment") private $!{tool.getClsNameByFullName($column.type)} $!{column.name}; #end }
Mapper接口改動以下後端
##定義初始變量 #set($tableName = $tool.append($tableInfo.name, "Mapper")) ##設置回調 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/mapper")) ##拿到主鍵 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mapper; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; /** * $!{tableInfo.comment}($!{tableInfo.name})表數據庫訪問層 * * @author $!author * @since $!time.currTime() */ @Mapper @Repository public interface $!{tableName} { /** * 經過ID查詢單條數據 * * @param $!pk.name 主鍵 * @return 實例對象 */ $!{tableInfo.name} queryById($!pk.shortType $!pk.name); /** * 查詢指定行數據 * * @param offset 查詢起始位置 * @param limit 查詢條數 * @return 對象列表 */ List<$!{tableInfo.name}> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit); /** * 經過實體做爲篩選條件查詢 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 對象列表 */ List<$!{tableInfo.name}> queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})); /** * 新增數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 影響行數 */ int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})); /** * 修改數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 影響行數 */ int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})); /** * 經過主鍵刪除數據 * * @param $!pk.name 主鍵 * @return 影響行數 */ int deleteById($!pk.shortType $!pk.name); }
##引入mybatis支持 $!mybatisSupport ##設置保存名稱與保存位置 $!callback.setFileName($tool.append($!{tableInfo.name}, "Mapper.xml")) $!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper")) ##拿到主鍵 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="$!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper"> <resultMap type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}" id="$!{tableInfo.name}Map"> #foreach($column in $tableInfo.fullColumn) <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/> #end </resultMap> <!--查詢單個--> <select id="queryById" resultMap="$!{tableInfo.name}Map"> select #allSqlColumn() from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name where $!pk.obj.name = #{$!pk.name} </select> <!--查詢指定行數據--> <select id="queryAllByLimit" resultMap="$!{tableInfo.name}Map"> select #allSqlColumn() from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name limit #{offset}, #{limit} </select> <!--經過實體做爲篩選條件查詢--> <select id="queryAll" resultMap="$!{tableInfo.name}Map"> select #allSqlColumn() from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name <where> #foreach($column in $tableInfo.fullColumn) <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end"> and $!column.obj.name = #{$!column.name} </if> #end </where> </select> <!--新增全部列--> <insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true"> insert into $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end) values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end) </insert> <!--經過主鍵修改數據--> <update id="update"> update $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name} <set> #foreach($column in $tableInfo.otherColumn) <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end"> $!column.obj.name = #{$!column.name}, </if> #end </set> where $!pk.obj.name = #{$!pk.name} </update> <!--經過主鍵刪除--> <delete id="deleteById"> delete from $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name} </delete> </mapper>
服務方法改動以下,這裏我省略了 service 接口,而直接生成實現類。若是習慣於接口+實現類的使用方法能夠保留接口和實現類,將@Servcie註解添加到接口上, Controller中繼續注入接口
##定義初始變量 #set($tableName = $tool.append($tableInfo.name, "Service")) ##設置回調 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/service")) ##拿到主鍵 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import $!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * $!{tableInfo.comment}($!{tableInfo.name})表服務實現類 * * @author $!author * @since $!time.currTime() */ @Service("$!tool.firstLowerCase($!{tableInfo.name})Service") public class $!{tableName} { @Autowired private $!{tableInfo.name}Mapper $!tool.firstLowerCase($!{tableInfo.name})Mapper; /** * 經過ID查詢單條數據 * * @param $!pk.name 主鍵 * @return 實例對象 */ public $!{tableInfo.name} queryById($!pk.shortType $!pk.name) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryById($!pk.name); } /** * 查詢多條數據 * * @param offset 查詢起始位置 * @param limit 查詢條數 * @return 對象列表 */ public List<$!{tableInfo.name}> queryAllByLimit(int offset, int limit) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryAllByLimit(offset, limit); } /** * 新增數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 實例對象 */ public $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) { this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.insert($!tool.firstLowerCase($!{tableInfo.name})); return $!tool.firstLowerCase($!{tableInfo.name}); } /** * 修改數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 實例對象 */ public $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) { this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.update($!tool.firstLowerCase($!{tableInfo.name})); return this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)()); } /** * 經過主鍵刪除數據 * * @param $!pk.name 主鍵 * @return 是否成功 */ public boolean deleteById($!pk.shortType $!pk.name) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.deleteById($!pk.name) > 0; } }
控制層主要作了以下改動,
##定義初始變量 #set($tableName = $tool.append($tableInfo.name, "Controller")) ##設置回調 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/controller")) ##拿到主鍵 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service; import org.springframework.web.bind.annotation.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; /** * $!{tableInfo.comment}($!{tableInfo.name})表控制層 * * @author $!author * @since $!time.currTime() */ @Api(tags = "$!{tableInfo.comment}($!{tableInfo.name})") @RestController @RequestMapping("$!tool.firstLowerCase($tableInfo.name)") public class $!{tableName} { /** * 服務對象 */ @Autowired private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service; /** * 經過主鍵查詢單條數據 * * @param id 主鍵 * @return 單條數據 */ @ApiOperation(value = "根據id查詢 $!{tableInfo.comment}") @GetMapping("selectOne/{id}") public $!{tableInfo.name} selectOne(@ApiParam(value = "$!pk.comment ID") @PathVariable("id") $!pk.shortType id) { return this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id); } }
說明文檔:
屬性
$author 設置中的做者 java.lang.String
$encode 設置的編碼 java.lang.String
$modulePath 選中的module路徑 java.lang.String
$projectPath 項目絕對路徑 java.lang.String
對象 $tableInfo 表對象 obj 表原始對象 com.intellij.database.model.DasTable name 表名(轉換後的首字母大寫)java.lang.String comment 表註釋 java.lang.String fullColumn 全部列 java.util.List<ColumnInfo> pkColumn 主鍵列 java.util.List<ColumnInfo> otherColumn 其餘列 java.util.List<ColumnInfo>,除主鍵之外的列 savePackageName 保存的包名 java.lang.String savePath 保存路徑 java.lang.String saveModelName 保存的model名稱 java.lang.String columnInfo 列對象 obj 列原始對象 com.intellij.database.model.DasColumn name 列名(首字母小寫) java.lang.String comment 列註釋 java.lang.String type 列類型(類型全名) java.lang.String shortType 列類型(短類型) java.lang.String custom 是否附加列 java.lang.Boolean ext 附加字段(Map類型) java.lang.Map<java.lang.String, java.lang.Object> $tableInfoList java.util.List<TableInfo>全部選中的表 $importList 全部須要導入的包集合 java.util.Set<java.lang.String> 回調 &callback setFileName(String) 設置文件儲存名字 setSavePath(String) 設置文件儲存路徑,默認使用選中路徑 工具 $tool firstUpperCase(String name) 首字母大寫方法 firstLowerCase(String name) 首字母小寫方法 getClsNameByFullName(String fullName) 經過包全名獲取類名 getJavaName(String name) 將下劃線分割字符串轉駝峯命名(屬性名) getClassName(String name) 將下劃線分割字符串轉駝峯命名(類名) append(Object... objs) 多個數據進行拼接 newHashSet(Object... objs) 建立一個HashSet對象 newArrayList(Object... objs) 建立一個ArrayList對象 newLinkedHashMap() 建立一個LinkedHashMap()對象 newHashMap() 建立一個HashMap()對象 getField(Object obj, String fieldName) 獲取對象的屬性值,能夠訪問任意修飾符修飾的屬性.配合debug方法使用. call(Object... objs) 空白執行方法,用於調用某些方法時消除返回值 debug(Object obj) 調式方法,用於查詢對象結構.可查看對象全部屬性與public方法 serial() 隨機獲取序列化的UID service(String serviceName, Object... param)遠程服務調用 parseJson(String) 將字符串轉Map對象 toJson(Object, Boolean) 將對象轉json對象,Boolean:是否格式化json,不填時爲不格式化。 $time currTime(String format) 獲取當前時間,指定時間格式(默認:yyyy-MM-dd HH:mm:ss) $generateService run(String, Map<String,Object>) 代碼生成服務,參數1:模板名稱,參數2:附加參數。
點擊Idea右邊的DataBase選項卡,選擇剛剛鏈接的數據庫,選好對應的表格,點擊右鍵選擇 EasyCode -> Generate Code, 若是出現下面的提示,就複製類型後面的字段,到第2步進行配置
配置完成後從新點擊 Generate Code 會出現以下的配置框,選好路徑後點擊OK,就會生成對應的代碼。
以後啓動項目,訪問Swagger路徑就能夠看到對應的配置已經徹底自動化生成。這樣咱們只須要在建立表的時候對字段進行註釋,就能夠實現 Entity中和先後端交互時的自動化註釋。很是方便
我是 Keats @後青春期的Keats ,一個熱愛技術的程序員,鑑於技術有限,若是本文有什麼紕漏或者兄臺還有其餘更好的建議/實現方式,歡迎留言評論,謝謝您!