用到的框架:springboot+mybatis+lombok+mysql5.7
使用mybatis開發的一大痛點就是搭建一些重復性的代碼很多,相比起來的話用JPA就很容易了!所以我們需要簡化mybatis的各種操作,其實就是自己生成一些代碼;生成模板代碼的方式有很多,如果是公司內部的話肯定也有自己的一套代碼生成工具,但是我們平常寫自己的項目的話,還是用自己喜歡的模板來寫比較好!
第一種:最原始的mybatis逆向工程的方式,這個應該很熟悉,就是可以自動生成表對應的po,mapper和xml
第二種:就是用easycode插件直接生成表對應的controller,service,mapper和xml的常用的crud,減少代碼量,用於我們平常自己寫項目的時候比較實用;這也是下面會仔細說的
第三種:有開源的項目可以直接一鍵生成vue和后端spingboot的所有代碼,推薦人人開源的一個代碼生成器,點擊這里,有興趣的可以用一下,賊好用,而且還有可視化頁面!
對於我們自己使用的話就沒有必要那么華麗呼哨的了,這里就用第二種吧!,首先用spring Initializer隨便創建一個springboot項目,務必使用阿里雲的這個地址,spring的創建項目的東東賊雞兒慢!!!
· https://start.aliyun.com/
使用idea連接mysql數據庫,這個很容易,不在本篇教程之內,參考這個老哥的教程,連接成功之后是這個樣子的(記得idea下載easycode插件然后重啟):
然后我們隨便新建一張t_user表:
create table t_user ( id int auto_increment primary key, username char(255) null, password varchar(255) null )charset = utf8;
然后根據:file->settings->Other Settings->Template Setting,新建分組,之后就是把我圖中那些.java文件給創建出來(根據自己的需要進行修改生成規則,我也是參考別人的代碼改了好多)
entity.java

##引入宏定義 $!define $!init ##使用宏定義設置回調(保存位置與文件后綴) #save("/entity", ".java") ##使用宏定義設置包后綴 #setPackageSuffix("entity") ##使用全局變量實現默認包導入 $!autoImport import java.io.Serializable; import lombok.Data; ##使用宏定義實現類注釋信息 #tableComment("實體類") @Data public class $!{tableInfo.name} implements Serializable { private static final long serialVersionUID = $!tool.serial(); #foreach($column in $tableInfo.fullColumn) #if(${column.comment})/** * ${column.comment} */#end private $!{tool.getClsNameByFullName($column.type)} $!{column.name}; #end }
controller.java

##定義初始變量 #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 lombok.extern.slf4j.Slf4j; import com.github.pagehelper.PageInfo; import $!{tableInfo.savePackageName}.response.PageResult; import $!{tableInfo.savePackageName}.response.Result; import $!{tableInfo.savePackageName}.response.StatusCode; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service; import org.springframework.web.bind.annotation.*; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.List; import java.util.Objects; /** * $!{tableInfo.comment}($!{tableInfo.name})控制層 * * @author protagonist * @since $!time.currTime() */ @RestController @Slf4j @RequestMapping("/$!tool.firstLowerCase($tableInfo.name)") public class $!{tableName} { /** * 服務對象 */ @Resource private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)ServiceImpl; /** * 通過主鍵查詢單條數據 * * @param $!pk.name 主鍵 * @return 單條數據 */ @GetMapping(value = "/get/{$!pk.name}") public Result selectOne(@PathVariable("$!pk.name") $!pk.shortType $!pk.name) { $tableInfo.name result = $!{tool.firstLowerCase($tableInfo.name)}ServiceImpl.selectById(id); if(Objects.nonNull(result)){ return new Result<>(true,StatusCode.OK,"查詢成功",result); } return new Result<>(true,StatusCode.ERROR,"查詢失敗"); } /** * 新增一條數據 * * @param $!tool.firstLowerCase($tableInfo.name) 實體類 * @return Result對象 */ @PostMapping(value = "/insert") public Result insert(@RequestBody $tableInfo.name $!tool.firstLowerCase($tableInfo.name)) { int result = $!{tool.firstLowerCase($tableInfo.name)}ServiceImpl.insert($!tool.firstLowerCase($tableInfo.name)); if (result > 0) { return new Result<>(true,StatusCode.OK,"新增成功",result); } return new Result<>(true,StatusCode.ERROR,"新增失敗"); } /** * 修改一條數據 * * @param $!tool.firstLowerCase($tableInfo.name) 實體類 * @return Result對象 */ @PutMapping(value = "/update") public Result update(@RequestBody $tableInfo.name $!tool.firstLowerCase($tableInfo.name)) { $tableInfo.name result = $!{tool.firstLowerCase($tableInfo.name)}ServiceImpl.update($!tool.firstLowerCase($tableInfo.name)); if (Objects.nonNull(result)) { return new Result<>(true,StatusCode.OK,"修改成功",result); } return new Result<>(true,StatusCode.ERROR,"修改失敗"); } /** * 刪除一條數據 * * @param $!pk.name 主鍵 * @return Result對象 */ @DeleteMapping(value = "/delete/{$!pk.name}") public Result delete(@PathVariable("$!pk.name") $!pk.shortType $!pk.name) { int result = $!{tool.firstLowerCase($tableInfo.name)}ServiceImpl.deleteById($!pk.name); if (result > 0) { return new Result<>(true,StatusCode.OK,"刪除成功",result); } return new Result<>(true,StatusCode.ERROR,"刪除失敗"); } /** * 查詢全部 * * @return Result對象 */ @GetMapping(value = "/selectAll") public Result<List<$tableInfo.name>> selectAll() { List<$tableInfo.name> $!tool.firstLowerCase($tableInfo.name)s = $!{tool.firstLowerCase($tableInfo.name)}ServiceImpl.selectAll(); if (CollectionUtils.isEmpty($!tool.firstLowerCase($tableInfo.name)s)) { return new Result<>(true,StatusCode.ERROR,"查詢全部數據失敗"); } return new Result<>(true,StatusCode.OK,"查詢全部數據成功",$!tool.firstLowerCase($tableInfo.name)s); } /** * 分頁查詢 * * @param current 當前頁 第零頁和第一頁的數據是一樣 * @param size 每一頁的數據條數 * @return Result對象 */ @GetMapping(value = "/selectPage/{current}/{size}") public Result selectPage(@PathVariable("current") Integer current,@PathVariable("size") Integer size) { PageInfo<$tableInfo.name> page = $!{tool.firstLowerCase($tableInfo.name)}ServiceImpl.selectPage(current, size); if (Objects.nonNull(page)) { return new Result<>(true,StatusCode.OK,"分頁條件查詢成功",new PageResult<>(page.getTotal(),page.getList())); } return new Result<>(true,StatusCode.ERROR,"分頁查詢數據失敗"); } }
service.java

##定義初始變量 #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 java.util.List; import com.github.pagehelper.PageInfo; /** * $!{tableInfo.comment}($!{tableInfo.name})表服務接口 * * @author protagonist * @since $!time.currTime() */ public interface $!{tableName} { /** * 通過ID查詢單條數據 * * @param $!pk.name 主鍵 * @return 實例對象 */ $!{tableInfo.name} selectById($!pk.shortType $!pk.name); /** * 分頁查詢 * * @param current 當前頁 * @param size 每一頁數據的條數 * @return 對象列表 */ PageInfo<$!{tableInfo.name}> selectPage(int current, int size); /** * 查詢全部 * * @return 對象列表 */ List<$!{tableInfo.name}> selectAll(); /** * 通過實體作為篩選條件查詢 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 對象列表 */ List<$!{tableInfo.name}> selectList($!{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})s 實例對象的集合 * @return 影響行數 */ int batchInsert(List<$!{tableInfo.name}> $!tool.firstLowerCase($!{tableInfo.name})s); /** * 修改數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 修改 */ $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})); /** * 通過主鍵刪除數據 * * @param $!pk.name 主鍵 * @return 影響行數 */ int deleteById($!pk.shortType $!pk.name); /** * 查詢總數據數 * * @return 數據總數 */ int count(); }
serviceImpl.java

##定義初始變量 #set($tableName = $tool.append($tableInfo.name, "ServiceImpl")) ##設置回調 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl")) ##拿到主鍵 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import $!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao; import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import javax.annotation.Resource; import java.util.List; /** * $!{tableInfo.comment}($!{tableInfo.name}表)服務實現類 * * @author protagonist * @since $!time.currTime() */ @Service("$!tool.firstLowerCase($!{tableInfo.name})ServiceImpl") public class $!{tableName} implements $!{tableInfo.name}Service { @Resource private $!{tableInfo.name}Dao $!tool.firstLowerCase($!{tableInfo.name})Dao; /** * 通過ID查詢單條數據 * * @param $!pk.name 主鍵 * @return 實例對象 */ @Override public $!{tableInfo.name} selectById($!pk.shortType $!pk.name) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.selectById($!pk.name); } /** * 分頁查詢 * * @param current 當前頁 * @param size 每一頁的條數 * @return 對象列表 */ @Override public PageInfo<$!{tableInfo.name}> selectPage(int current, int size) { PageHelper.startPage(current,size); List<$!{tableInfo.name}> dataList = $!{tool.firstLowerCase($!{tableInfo.name})}Dao.selectAll(); return new PageInfo<>(dataList); } /** * 查詢所有 * * @return 實例對象的集合 */ @Override public List<$!{tableInfo.name}> selectAll() { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.selectAll(); } /** * 根據條件查詢 * * @return 實例對象的集合 */ @Override public List<$!{tableInfo.name}> selectList($!{tableInfo.name} $!{tool.firstLowerCase($!{tableInfo.name})}) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.selectList($!{tool.firstLowerCase($!{tableInfo.name})}); } /** * 新增數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 實例對象 */ @Override @Transactional public int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.insert($!tool.firstLowerCase($!{tableInfo.name})); } /** * 批量新增 * * @param $!tool.firstLowerCase($!{tableInfo.name})s 實例對象的集合 * @return 生效的條數 */ @Override @Transactional public int batchInsert(List<$!{tableInfo.name}> $!tool.firstLowerCase($!{tableInfo.name})s) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.batchInsert($!tool.firstLowerCase($!{tableInfo.name})s); } /** * 修改數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 實例對象 */ @Override @Transactional public $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) { this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.update($!tool.firstLowerCase($!{tableInfo.name})); return this.selectById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)()); } /** * 通過主鍵刪除數據 * * @param $!pk.name 主鍵 * @return 是否成功 */ @Override @Transactional public int deleteById($!pk.shortType $!pk.name) { return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.deleteById($!pk.name); } /** * 查詢總數據數 * * @return 數據總數 */ @Override public int count(){ return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.count(); } }
dao.java

##定義初始變量 #set($tableName = $tool.append($tableInfo.name, "Dao")) ##設置回調 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/dao")) ##拿到主鍵 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * $!{tableInfo.comment}($!{tableInfo.name})表數據庫訪問層 * * @author protagonist * @since $!time.currTime() */ @Mapper public interface $!{tableName} { /** * 通過ID查詢單條數據 * * @param $!pk.name 主鍵 * @return 實例對象 */ $!{tableInfo.name} selectById($!pk.shortType $!pk.name); /** * 查詢全部 * * @return 對象列表 */ List<$!{tableInfo.name}> selectAll(); /** * 通過實體作為篩選條件查詢 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 對象列表 */ List<$!{tableInfo.name}> selectList($!{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})s 實例對象的集合 * @return 影響行數 */ int batchInsert(List<$!{tableInfo.name}> $!tool.firstLowerCase($!{tableInfo.name})s); /** * 修改數據 * * @param $!tool.firstLowerCase($!{tableInfo.name}) 實例對象 * @return 影響行數 */ int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})); /** * 通過主鍵刪除數據 * * @param $!pk.name 主鍵 * @return 影響行數 */ int deleteById($!pk.shortType $!pk.name); /** * 查詢總數據數 * * @return 數據總數 */ int count(); }
mapper.xml

##引入mybatis支持 $!mybatisSupport ##設置保存名稱與保存位置 $!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.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}.dao.$!{tableInfo.name}Dao"> <!-- 結果集 --> <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> <!-- 基本字段 --> <sql id="Base_Column_List"> #allSqlColumn() </sql> <!-- 查詢單個 --> <select id="selectById" resultMap="$!{tableInfo.name}Map"> select <include refid="Base_Column_List" /> from $!tableInfo.obj.name where $!pk.obj.name = #{$!pk.name} </select> <!-- 查詢全部 --> <select id="selectAll" resultMap="$!{tableInfo.name}Map"> select <include refid="Base_Column_List" /> from $!tableInfo.obj.name </select> <!--通過實體作為篩選條件查詢--> <select id="selectList" resultMap="$!{tableInfo.name}Map"> select <include refid="Base_Column_List" /> from $!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.name}(#foreach($column in $tableInfo.fullColumn)$!column.obj.name#if($velocityHasNext), #end#end) values ( #foreach($column in $tableInfo.fullColumn)#{$!{column.name}}#if($velocityHasNext), #end#end) </insert> <!-- 批量新增 --> <insert id="batchInsert"> insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.fullColumn)$!column.obj.name#if($velocityHasNext), #end#end) values <foreach collection="$!tool.firstLowerCase($!{tableInfo.name})s" item="item" index="index" separator=","> ( #foreach($column in $tableInfo.fullColumn) #{item.$!{column.name}}#if($velocityHasNext), #end #end ) </foreach> </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.name} where $!pk.obj.name = #{$!pk.name} </delete> <!-- 總數 --> <select id="count" resultType="int"> select count(*) from $!{tableInfo.obj.name} </select> </mapper>
Result.java

##設置回調 $!callback.setFileName($tool.append("Result", ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/response")) #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}response; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /**用於封裝返回給前端的結果 * @author protagonist * @title: StatusCode * @description: TODO * @date $!time.currTime() */ @Data @NoArgsConstructor @AllArgsConstructor public class Result<T> { private boolean flag; private Integer code; private String message; private T data; public Result(boolean flag, int code, String message) { this.flag = flag; this.code = code; this.message = message; } }
PageResult.java

##設置回調 $!callback.setFileName($tool.append("PageResult", ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/response")) #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}response; ##使用全局變量實現默認包導入 $!autoImport import lombok.Data; import java.util.List; /**分頁結果對象 * @author protagonist * @title: PageResult * @description: TODO * @date $!time.currTime() */ @Data public class PageResult<T> { private Long total; private List<T> rows; public PageResult(Long total, List<T> rows) { this.total = total; this.rows = rows; } }
StateCode.java

##設置回調 $!callback.setFileName($tool.append("StatusCode", ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/response")) #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}response; /**錯誤碼常量類 * @author protagonist * @title: StatusCode * @description: TODO * @date $!time.currTime() */ public class StatusCode { public static final int OK=20000;//成功 public static final int ERROR =20001;//失敗 public static final int LOGINERROR =20002;//用戶名或密碼錯誤 public static final int ACCESSERROR =20003;//權限不足 public static final int REMOTEERROR =20004;//遠程調用失敗 public static final int REPERROR =20005;//重復操作 }
還有個地方可能需要配置一下,因為數據庫中有的表有前綴,比如t_user這種,我們可能想把前綴干掉,如下所示:
## 去掉前綴 #if($tableInfo.obj.name.startsWith("t_")) $!tableInfo.setName($tool.getClassName($tableInfo.obj.name.substring(2))) #end
到這里其實就已經結束了,之后填寫基本的信息,然后就是狂點yes,代碼就生成了;
生成代碼之后的目錄是這樣的,我們再把mybatis需要的分頁插件pageheper依賴導入,然后連接數據庫的配置文件弄一下,就ok了;
properties配置文件:
# 應用名稱 spring.application.name=template # 應用服務 WEB 訪問端口 server.port=8090 # spring 靜態資源掃描路徑 spring.resources.static_locations=classpath:/static/ #分頁插件 pagehelper.helper-dialect=mysql pagehelper.reasonable=true pagehelper.support-methods-arguments=true pagehelper.params=count=countSql #配置Mysql連接 spring.datasource.url=jdbc:mysql://localhost:3306/white_jotter?characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #配置mybatis #配置實體類別名 mybatis.type-aliases-package=com/protagonist/template/entity #配置xml映射路徑 mybatis.mapper-locations=classpath*:/mapper/**.xml #開啟駝峰命名法 mybatis.configuration.map-underscore-to-camel-case=true
pom.xml把下面幾個關鍵的導入就行了
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency>
啟動項目,訪問controller,來個分頁查詢,可以看到返回的數據格式這就是通用的,前端只需要判斷狀態碼然后拿數據就行了;
別看這個博客很多,其實很少,有興趣的可以把模板代碼根據自己的需要進行魔改,還可以多加幾個自己覺得常用的方法,而且這里還是有點問題,應該再來一個VO包,前后端的交互的VO應該放在這里,和entity中的類區分開,這里就不弄這么麻煩了,自己魔改吧!
再說一點,其實這種方式生成的代碼還是比較多,如果你會使用mybatisplus的話,那自己修改一下模板,生成springboot+mybatisplus+mybatis+lombok+mysql的代碼,生成代碼就更少了,有興趣的可以自己弄一下!!!
一定要有耐心弄一個適合自己的模板,這樣以后直接用很方便,不然看別人的代碼每個人的習慣都不一樣,很難受!!!