實戰(zhàn):一鍵生成前后端代碼,Mybatis-Plus代碼生成器讓我舒服了
前言
在日常的軟件開發(fā)中,程序員往往需要花費大量的時間寫CRUD,不僅枯燥效率低,而且每個人的代碼風格不統(tǒng)一。MyBatis-Plus 代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模塊及前端頁面的代碼,極大的提升了開發(fā)效率。
項目介紹
本項目將以springboot用演示,前端使用freemaker,數(shù)據(jù)庫持久層用mybatis(考慮到mybatis的使用還是最普遍的,就沒有用jpa和mybatisplus),通過Velocity模板引擎配置各模塊的文件模板,通過mybatis-plus代碼生成器連接mysql,用商品表為例生成各模塊的代碼和前端頁面。(本項目只演示分頁查詢和導出功能)。
本項目所有代碼和腳本都能都文末找到地址。
實戰(zhàn)
數(shù)據(jù)庫腳本
創(chuàng)建一張商品表test_goods
CREATE?TABLE?`test_goods`?(
??`id`?bigint(20)?DEFAULT?NULL?COMMENT?'id',
??`goods_sn`?varchar(45)?DEFAULT?NULL?COMMENT?'商品編碼',
??`name`?varchar(255)?DEFAULT?NULL?COMMENT?'商品名稱',
??`title`?varchar(80)?DEFAULT?NULL?COMMENT?'標題',
??`price`?decimal(10,2)?DEFAULT?NULL?COMMENT?'售價',
??`status`?int(2)?DEFAULT?NULL?COMMENT?'商品狀態(tài)',
??`sale_count`?int(11)?DEFAULT?NULL?COMMENT?'銷量',
??`create_date`?datetime?DEFAULT?NULL?COMMENT?'創(chuàng)建時間',
??`modify_date`?datetime?DEFAULT?NULL?COMMENT?'修改時間'
)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8
maven依賴
??<dependencies>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-webartifactId>
????????dependency>
????????<dependency>
????????????<groupId>org.mybatis.spring.bootgroupId>
????????????<artifactId>mybatis-spring-boot-starterartifactId>
????????????<version>2.1.2version>
????????dependency>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-data-redisartifactId>
????????dependency>
????????<dependency>
????????????<groupId>com.baomidougroupId>
????????????<artifactId>mybatis-plusartifactId>
????????????<version>2.1.4version>
????????dependency>
????????
????????<dependency>
????????????<groupId>org.aspectjgroupId>
????????????<artifactId>aspectjweaverartifactId>
????????????<scope>providedscope>
????????dependency>
????????
????????
????????<dependency>
????????????<groupId>org.projectlombokgroupId>
????????????<artifactId>lombokartifactId>
????????????<version>1.16.10version>
????????????<scope>providedscope>
????????dependency>
????????<dependency>
????????????<groupId>org.apache.velocitygroupId>
????????????<artifactId>velocity-engine-coreartifactId>
????????????<version>2.0version>
????????dependency>
????????<dependency>
????????????<groupId>mysqlgroupId>
????????????<artifactId>mysql-connector-javaartifactId>
????????????<scope>runtimescope>
????????dependency>
??
????????<dependency>
????????????<groupId>com.opencsvgroupId>
????????????<artifactId>opencsvartifactId>
????????????<version>3.8version>
????????dependency>
??
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-freemarkerartifactId>
????????dependency>
????dependencies>
配置文件
mybatis:
??mapper-locations:?classpath:mybatis/*Mapper.xml
??type-aliases-package:?com.lzn.mybatisplus.codegenerator.entity
spring:
??datasource:
????username:?root
????password:?123qwe
????url:?jdbc:mysql://192.168.0.1:3306/myProject?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
????driver-class-name:?com.mysql.jdbc.Driver
??redis:
????host:?192.168.0.1
????password:?1234qwer
????port:?6379
??freemarker:
????template-loader-path:?classpath:/templates/pages/
????cache:?false
????charset:?UTF-8
????check-template-location:?true
????content-type:?text/html
????expose-request-attributes:?true
????expose-session-attributes:?true
????suffix:?.ftl
模板文件
本項目中,所有模塊的文件都是用Velocity模板引擎生成,這里簡單介紹下Velocity的語法,在Velocity中用{table.entityName} 表示實體名,{author}、field in ${table.fields}) ?#end遍歷表字段。下面演示幾個類、前端文件、xml文件的模板文件
實體類模板(entity.java.vm)
package?${package.Entity};
import?java.math.BigDecimal;
import?java.util.Date;
import?lombok.Getter;
import?lombok.Setter;
import?lombok.ToString;
/**
?*?數(shù)據(jù)庫表名?${table.name}
?*
?*?@author?${author}
?*?@date?${date}
?*/
@Getter
@Setter
@ToString
public?class?${table.entityName}??{
????#foreach($field?in?${table.fields})
????/**
?????*?數(shù)據(jù)庫字段名?${field.name}?類型?${field.type}
?????*/
????private?${field.propertyType}??${field.propertyName};
????#end
}
Controller模板(controller.java.vm)
package?${package.Controller};
import?${package.Entity}.${entity};
import?${package.Service}.${table.serviceName};
import?com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO;
import?com.lzn.mybatisplus.codegenerator.export.${table.entityName}ExportService;
import?com.lzn.mybatisplus.codegenerator.utils.entity.*;
import?com.lzn.mybatisplus.codegenerator.utils.export.*;
import?org.apache.commons.beanutils.ConvertUtils;
import?com.lzn.mybatisplus.codegenerator.utils.ParameterUtil;
import?com.lzn.mybatisplus.codegenerator.utils.entity.GridDataModel;
import?org.slf4j.Logger;
import?org.slf4j.LoggerFactory;
import?org.springframework.stereotype.Controller;
import?org.springframework.ui.Model;
import?org.springframework.web.bind.annotation.*;
import?javax.annotation.Resource;
import?javax.servlet.ServletRequest;
import?javax.servlet.http.HttpServletRequest;
import?java.util.List;
import?java.util.Map;
/**
?*?
?*?${tablecomment}??前端控制器
?*?
?*
?*?@author?${author}
?*?@since?${date}
?*/
@Controller
@RequestMapping(value="/admin/${table.entityPath}")
public?class?${table.controllerName}{
????private?static?Logger?logger?=?LoggerFactory.getLogger(${table.controllerName}.class);
????@Resource
????private?${entity}Service?${table.entityPath}Service;
????@RequestMapping(value?=?"list",?method?=?RequestMethod.GET)
????public?String?list(Model?model){
????????return?"/admin/${cfg.pageDirName}/list";
????}
????@RequestMapping(value?=?"searchList",?method?=?RequestMethod.POST)
????@ResponseBody
????@ExportMethod(serviceClass?=?${entity}ExportService.class,?memo?=?"明細導出")
????public?String?searchList(ServletRequest?request,@ModelAttribute("page")??OmuiPage?page){
????????try?{
????????????Map?searchParam?=????ParameterUtil.getParametersStartingWith(request,?"filter_");
????????????GridDataModel<${entity}VO>?gd?=${table.entityPath}Service.findByPage(searchParam,?page);
????????????return?JsonMapper.nonDefaultMapper().toJson(gd);
????????}?catch?(Exception?e)?{
????????????logger.error("查詢出錯了",e);
????????????return?JsonMapper.nonDefaultMapper().toJson(new?Resp("false",?e.getMessage()));
????????}
????}
}
Service類模板(service.java.vm)
package?${package.Service};
import?org.springframework.stereotype.Service;
import?com.lzn.mybatisplus.codegenerator.dao.${table.mapperName};
import?com.lzn.mybatisplus.codegenerator.utils.entity.GridDataModel;
import?com.lzn.mybatisplus.codegenerator.utils.entity.OmuiPage;
import?com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO;
import?javax.annotation.Resource;
import?java.math.BigDecimal;
import?java.text.DateFormat;
import?java.text.ParseException;
import?java.text.SimpleDateFormat;
import?java.util.*;
/**
?*?
?*?$!{tablecomment}?服務類
?*?
?*
?*?@author?${author}
?*?@since?${date}
?*/
@Service
public?class?${table.serviceName}?{
????@Resource
????private?${table.mapperName}?${table.entityPath}Dao;
????/**
?????*?分頁查詢
?????*?*/
????public?GridDataModel<${table.entityName}VO>??findByPage(Map?searchParams,?OmuiPage?page){
????????GridDataModel<${table.entityName}VO>?gm?=?new?GridDataModel<${table.entityName}VO>();
????????searchParams.put("start",?page.getStart());
????????searchParams.put("limit",?page.getLimit());
????????long?count?=?${table.entityPath}Dao.countForPage(searchParams);
????????List<${table.entityName}VO>?list?=?${table.entityPath}Dao.listForPage(searchParams);
????????gm.setTotal(count);
????????gm.setRows(list);
????????return?gm;
????}
}
Dao類模板(dao.java.vm)
package?${package.Mapper};
import?com.lzn.mybatisplus.codegenerator.entity.${table.entityName};
import?com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO;
import?java.util.List;
import?java.util.Map;
public?interface?${table.mapperName}??{
????/**
?????*??根據(jù)主鍵刪除數(shù)據(jù)庫的記錄,?${table.name}
?????*/
????int?deleteByPrimaryKey(Long?id);
????/**
?????*??新寫入數(shù)據(jù)庫記錄,?${table.name}
?????*/
????int?insert(${table.entityName}?record);
????/**
?????*??根據(jù)指定主鍵獲取一條數(shù)據(jù)庫記錄,?${table.name}
?????*/
????${table.entityName}?selectByPrimaryKey(Long?id);
????/**
?????*??根據(jù)主鍵來更新符合條件的數(shù)據(jù)庫記錄,?${table.name}
?????*/
????int?updateByPrimaryKey(${table.entityName}?record);
????/**
?????*??根據(jù)條件分頁查詢
?????*?*/
????List<${table.entityName}VO>?listForPage(Map?searchMap);
????/**
?????*??根據(jù)條件分頁查詢(計數(shù))
?????*?*/
????long?countForPage(Map?searchMap) ;
????
}
Mapper.xml模板(mapper.xml.vm)
<mapper?namespace="${package.Mapper}.${table.mapperName}">
????#if(${baseResultMap})
????????
????????<resultMap?id="BaseResultMap"?type="${package.Entity}.${entity}">
????????????#foreach($field?in?${table.fields})
????????????????#if(${field.keyFlag})##生成主鍵排在第一位
????????????????????<id?column="${field.name}"?property="${field.propertyName}"?/>
????????????????#end
????????????#end
????????????#foreach($field?in?${table.commonFields})##生成公共字段
????????????????<result?column="${field.name}"?property="${field.propertyName}"?/>
????????????#end
????????????#foreach($field?in?${table.fields})
????????????????#if(!${field.keyFlag})##生成普通字段
????????????????????<result?column="${field.name}"?property="${field.propertyName}"?/>
????????????????#end
????????????#end
????????resultMap>
????#end
????#if(${baseColumnList})
????????
????????<sql?id="Base_Column_List">
????????#foreach($field?in?${table.commonFields})
????????????#if(${field.name}?==?${field.propertyName})${field.name}#else${field.name}?AS?${field.propertyName}#end,
????????#end
????????${table.fieldNames}
????????sql>
????#end
????<delete?id="deleteByPrimaryKey"?parameterType="java.lang.Long">
????????
????????delete?from?${table.name}
????????where
????????#foreach($field?in?${table.fields})
????????????#if(${field.keyFlag})##?主鍵
????????????????${field.name}?=?#{?${field.propertyName}?}
????????????#end
????????#end
????delete>
????<insert?id="insert"?parameterType="${package.Entity}.${entity}">
????????
????????<selectKey?keyProperty="id"?order="AFTER"?resultType="java.lang.Long">
????????????SELECT?LAST_INSERT_ID()
????????selectKey>
????????insert?into?${table.name}?(
????????#foreach($field?in?${table.fields})
????????????#if(!${field.keyFlag})##生成普通字段
????????????????${field.name}#if($foreach.hasNext),#end
????????????#end
????????#end
????????)
????????values?(
????????#foreach($field?in?${table.fields})
????????????#if(!${field.keyFlag})##生成普通字段
????????????????#{?${field.propertyName}}#if($foreach.hasNext),#end
????????????#end
????????#end
????????)
????insert>
????<update?id="updateByPrimaryKey"?parameterType="${package.Entity}.${entity}">
????????
????????update?${table.name}
????????set
????????#foreach($field?in?${table.fields})
????????????#if(!${field.keyFlag})##生成普通字段
???????????????${field.name}?=?#{?${field.propertyName}}?#if($foreach.hasNext),#end
????????????#end
????????#end
????????where
????????#foreach($field?in?${table.fields})
????????????#if(${field.keyFlag})
??????????????id?=?#{?${field.name}?}
????????????#end
????????#end
????update>
????<select?id="selectByPrimaryKey"?parameterType="java.lang.Long"?resultMap="BaseResultMap">
????????
????????select
????????<include?refid="Base_Column_List"?/>
????????from?${table.name}
????????where?id?=?#{?id?}
????select>
????<select?id="countForPage"?parameterType="map"?resultType="Long">
????????
????????select
?????????count(*)
????????from
????????${table.name}
????????where?1=1
????????<if?test="beginDate?!=?null?and?beginDate?!=?''">
????????????and?create_date?=]]>??#{beginDate}
????????if>
????????<if?test="endDate?!=?null?and?endDate?!=?''">
????????????and??create_date??#{endDate}
????????if>
????select>
????<select?id="listForPage"?parameterType="map"??resultType="com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO">
????????
????????select
????????<include?refid="Base_Column_List"?/>
????????from
????????${table.name}
????????where?1=1
????????<if?test="beginDate?!=?null?and?beginDate?!=?''">
????????????and?create_date?=]]>??#{beginDate}
????????if>
????????<if?test="endDate?!=?null?and?endDate?!=?''">
????????????and??create_date??#{endDate}
????????if>
????????limit?#{start},?#{limit}
????select>
mapper>
前端頁面list.ftl模板(list.ftl.vm)
?<#assign?base=request.contextPath>
<html?xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta?http-equiv="content-type"?content="text/html;?charset=utf-8"?/>
<title>$!{tablecomment}title>
<link?href="${base}/static/omui/css/elegant/om-all.css"?rel="stylesheet"?type="text/css"?/>
<link?href="${base}/static/admin/css/admin.css"?rel="stylesheet"?type="text/css"?/>
<script?type="text/javascript"?src="${base}/static/js/jquery-1.7.1.js">script>
<script?type="text/javascript"?src="${base}/static/js/HForm.js">script>
<script?type="text/javascript"?src="${base}/static/My97DatePicker/WdatePicker.js">script>
<script?type="text/javascript"?src="${base}/static/omui/js/operamasks-ui.min.js">script>
<script?type="text/javascript"?src="${base}/static/omui/js/common.js">script>
<script?type="text/javascript"?src="${base}/static/bui/js/common.js">script>
<script?type="text/javascript"?src="${base}/static/admin/js/export.js">script>
<script?type="text/javascript">
???$().ready(function(){
??????//初始化控件
??????$("#search-panel").omPanel({
?????????title?:?"條件搜索",collapsible:false
??????});
??????//搜索
??????$('#searchButton').bind('click',?function(e)?{
???????????var?data?=?$("#listForm").HForm('form2json');
???????????$('#listGrid').omGrid({extraData:data});
??????});
??????$("#start-time").omCalendar();
??????$("#time-end").omCalendar();
???????$('#searchButton').omButton({
?????????icons?:?{left?:?'${base}/static/omui/images/search.png'},width?:?70
???????});
????????$(".input-select").change(function(){
????????????$('#searchButton').click();
????????});
??????$('#buttonbar').omButtonbar({
?????????btns?:?[{label:"導出Excel",
??????????????????id:"addbutton"?,
??????????????????icons?:?{left?:?'${base}/static/omui/images/export.png'},
??????????????????onClick:function()
?????????????????????{
????????????????????????exportUtil({
???????????????????????????title?:?"列表導出",
???????????????????????????exportUrl?:?"${base}/admin/${table.entityPath}/searchList",
???????????????????????????extraParam?:?$("#listForm").HForm('form2json')
????????????????????????});
?????????????????????}
??????????????????}
???????????????]
??????});
??????//初始化列表
??????var??height=$(document).height()?-$('#search-panel').outerHeight()-$('#buttonbar').outerHeight()-40;
??????$('#listGrid').omGrid({
?????????height:height,
?????????limit:20,
?????????method:'post',
?????????singleSelect:false,
?????????extraData:$("#listForm").HForm('form2json'),
?????????dataSource?:?'${base}/admin/${table.entityPath}/searchList',
?????????colModel?:?[
?????????????????????{header?:?'ID',?name?:?'id',?width?:?30,?align?:?'left',sort:'serverSide'},
??????????????????{header?:?'創(chuàng)建時間',?name?:?'createDate',?width?:?150,?align?:?'left',sort:'serverSide',renderer?:dataFormat1},
??????????????????{header?:?'修改時間',?name?:?'modifyDate',?width?:?150,?align?:?'left',sort:'serverSide',renderer?:dataFormat1},
#foreach($field?in?${table.fields})
#set($comment?=?"")
#set($type?=?"")
#set($isNullAble?=?true)
#set($defaultValue?=?false)
#set($listIsShow?=?true)
#set($listIsSearch?=?false)
#foreach(?$e?in?$field.comment.split(","))
????#if(?$foreach.count?==?1?)
????#set($comment?=?$e)
????#elseif(?$foreach.count?==?2?)
????#set($type?=?$e)
????#elseif(?$foreach.count?==?3)
????#if($e?==?"YES")
????#set($isNullAble?=?true)
????#else
????#set($isNullAble?=?false)
????#end
????#elseif(?$foreach.count?==?4)
????#if($e?==?"true")
????#set($defaultValue?=?true)
????#else
????#set($defaultValue?=?false)
????#end
????#elseif(?$foreach.count?==?5)
????#if($e?==?"true")
????#set($listIsShow?=?true)
????#else
????#set($listIsShow?=?false)
????#end
????#elseif(?$foreach.count?==?6)
????#if($e?==?"true")
????#set($listIsSearch?=?true)
????#else
????#set($listIsSearch?=?false)
????#end
????#end
#end
?????????{header?:?'#if("$!comment"?!=?"")${comment}#end',?name?:?'${field.propertyName}',width?:?90,?align?:?'left',sort:'serverSide'#if($type?==?"timer"),renderer?:dataFormat1?#end},
#end
?????????],
?????????rowDetailsProvider:function(rowData){
?????????}
??????});
??????//初始化控件??end
??????function?getIds(datas)?{
?????????var?str?=?"";
?????????for?(var?i?=?0;?i?datas.length;?i++)?{
????????????str?+=?datas[i].id?+?",";
?????????}
?????????//去掉最后一個逗號(如果不需要去掉,就不用寫)
?????????if?(str.length?>?0)?{
????????????str?=?str.substr(0,?str.length?-?1);
?????????}
?????????return?str;
??????}
??????$('#searchButton').click();
???});
script>
head>
<body?>
<div?id="search-panel">
????<form?id="listForm">
???<div>
??????<span?class="label">狀態(tài):span>
??????<select?class="js-example-basic-single?input-select"??name="filter_EQS_status">
?????????<option?value="0"?selected>待處理option>
?????????<option?value="1">已處理option>
?????????<option?value="">全部option>
??????select>
??????<span?class="label">手機號:span>
??????<input?type="text"?class="input-text"?name="filter_LIKES_mobile"?/>
??????<span?class="label">聯(lián)系人:span>
??????<input?type="text"?class="input-text"?name="filter_LIKES_name"?/>
??????<span?class="label">創(chuàng)建時間:span>
??????<input?id="start-time"?style="width:?118px"?name="filter_GTED_createDate"/>
??????-
??????<input?id="time-end"??style="width:?118px"?name="filter_LTED_createDate"/>
??????<span?id="searchButton">查詢span>
???div>
???form>
div>
<div?id="buttonbar">div>
<table?id="listGrid">table>?
body>
html>
代碼生成器
package?com.lzn.mybatisplus.codegenerator;
import?com.baomidou.mybatisplus.generator.AutoGenerator;
import?com.baomidou.mybatisplus.generator.InjectionConfig;
import?com.baomidou.mybatisplus.generator.config.*;
import?com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import?com.baomidou.mybatisplus.generator.config.po.TableInfo;
import?com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import?com.baomidou.mybatisplus.generator.config.rules.DbType;
import?com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import?java.util.ArrayList;
import?java.util.HashMap;
import?java.util.List;
import?java.util.Map;
/**
?*?輔助生產后臺開發(fā)相關代碼??開發(fā)時只在自己本地代碼修改,不要提交
?*?生成ddao?service?controller?entity?java代碼?和前端?flt文件。
?*?只演示list場景
?*/
public?class?MpGenerator?{
????//注意:開發(fā)時只在自己本地代碼修改,不要提交、不要提交?不要提交
????//第一步修改?javaSrcDir?修改成自己項目存放java源代碼的根路徑
????static?String?javaSrcDir?=?"D:/Git_space/lunzijihua/codegenerator/src/main/java";
????static?String?resourceDir?=?"D:/Git_space/lunzijihua/codegenerator/src/main/resources";
????//第二步修改?pageRootDir?修改成你要開發(fā)的模塊的名稱?存放ftl文件的文件夾的根路徑
????static?String?pageRootDir?="D:/Git_space/lunzijihua/codegenerator/src/main/resources/templates/pages/";
????//第三步修改?packageName?修改成你要開發(fā)的模塊的名稱?包名?要小寫?生產的entity?service?dao?action文件夾和java代碼會在下面
????static?String?packageName?=?"user";//模塊文件夾包名稱
????//第四步修改?pageDirName?修改成你要開發(fā)的模塊的名稱?存放ftl文件的文件夾?要小寫
????static?String?pageDirName?=?"user";//模塊頁面文件夾名
????//第五步驟?表的前綴?填寫了?生成文件時會去除掉
????static?String?tablePrefix="test_";
????//第六步?數(shù)據(jù)庫里面對應的表的全名
????static?String?tableName="test_goods";
????/**
?????*?
?????*?代碼自動生成
?????*?
?????*/
????public?static?void?main(String[]?args)?{
????????AutoGenerator?mpg?=?new?AutoGenerator();
????????//?全局配置
????????GlobalConfig?gc?=?new?GlobalConfig();
????????gc.setOutputDir(javaSrcDir);
????????gc.setFileOverride(true);
????????gc.setActiveRecord(true);//?不需要ActiveRecord特性的請改為false
????????gc.setEnableCache(false);//?XML?二級緩存
????????gc.setBaseResultMap(true);//?XML?ResultMap
????????gc.setBaseColumnList(true);//?XML?columList
????????//?.setKotlin(true)?是否生成?kotlin?代碼
????????gc.setAuthor("liuzhinan");
????????//?自定義文件命名,注意?%s?會自動填充表實體屬性!
????????gc.setMapperName("%sMybatisDao");
????????//?gc.setXmlName("%sDao");
????????gc.setServiceName("%sService");
//?????????gc.setServiceImplName("%sService");
????????//?gc.setControllerName("%sAction");
????????mpg.setGlobalConfig(gc);
????????//?數(shù)據(jù)源配置
????????DataSourceConfig?dsc?=?new?DataSourceConfig();
????????dsc.setDbType(DbType.MYSQL);
????????dsc.setTypeConvert(new?MySqlTypeConvert(){
????????????//?自定義數(shù)據(jù)庫表字段類型轉換【可選】
????????????@Override
????????????public?DbColumnType?processTypeConvert(String?fieldType)?{
????????????????System.out.println("轉換類型:"?+?fieldType);
????????????????//?注意??!processTypeConvert?存在默認類型轉換,如果不是你要的效果請自定義返回、非如下直接返回。
????????????????return?super.processTypeConvert(fieldType);
????????????}
????????});
????????dsc.setDriverName("com.mysql.jdbc.Driver");
????????dsc.setUsername("test");
????????dsc.setPassword("123456");
????????dsc.setUrl("jdbc:mysql://192.168.0.1:3306/myProject?useSSL=false");
????????mpg.setDataSource(dsc);
????????//?策略配置
????????StrategyConfig?strategy?=?new?StrategyConfig();
????????//?strategy.setCapitalMode(true);//?全局大寫命名?ORACLE?注意
????????strategy.setTablePrefix(new?String[]?{?tablePrefix?});//?此處可以修改為您的表前綴
????????strategy.setNaming(NamingStrategy.underline_to_camel);//?表名生成策略
????????strategy.setInclude(new?String[]?{?tableName?});?//?需要生成的表
????????//?strategy.setExclude(new?String[]{"test"});?//?排除生成的表
????????//?自定義實體父類
????????strategy.setSuperEntityClass("com.lzn.mybatisplus.codegenerator.entity.IdEntity");
????????//?自定義實體,公共字段
????????//??strategy.setSuperEntityColumns(new?String[]?{?"id",?"create_date","modify_date"?});
????????//?自定義?mapper?父類
????????//?strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
????????//?自定義?service?父類
????????//?strategy.setSuperServiceClass("com.baomidou.demo.TestService");
????????//?自定義?service?實現(xiàn)類父類
????????//?strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
????????//?自定義?controller?父類
????????//?strategy.setSuperControllerClass("com.baomidou.demo.TestController");
????????//?【實體】是否生成字段常量(默認?false)
????????//?public?static?final?String?ID?=?"test_id";
????????//?strategy.setEntityColumnConstant(true);
????????//?【實體】是否為構建者模型(默認?false)
????????//?public?User?setName(String?name)?{this.name?=?name;?return?this;}
????????//?strategy.setEntityBuilderModel(true);
????????mpg.setStrategy(strategy);
????????//?包配置
????????PackageConfig?pc?=?new?PackageConfig();
????????pc.setParent("com.lzn.mybatisplus.codegenerator");
????????pc.setModuleName(null);
????????pc.setMapper("dao");
????????pc.setEntity("entity");
????????pc.setService("service");
????????pc.setServiceImpl("service.impl");
????????pc.setController("controller");
????????mpg.setPackageInfo(pc);
????????//?注入自定義配置,可以在?VM?中使用?cfg.abc?【可無】
????????InjectionConfig?cfg?=?new?InjectionConfig()?{
????????????@Override
????????????public?void?initMap()?{
????????????????Map?map?=?new?HashMap();
????????????????map.put("abc",?this.getConfig().getGlobalConfig().getAuthor()?+?"-mp");
????????????????map.put("pageDirName",pageDirName);
????????????????map.put("packageName",packageName);
????????????????this.setMap(map);
????????????}
????????};
????????List?focList?=?new?ArrayList();
//????????cfg.setFileOutConfigList(focList);
//????????mpg.setCfg(cfg);
????????//生成導出視圖對象
????????focList.add(new?FileOutConfig("/templates/vm/vo.java.vm")?{
????????????@Override
????????????public?String?outputFile(TableInfo?tableInfo)?{
????????????????return?javaSrcDir+"/com/lzn/mybatisplus/codegenerator/export/"+tableInfo.getEntityName()+"VO.java";
????????????}
????????});
????????//生成excel導出的服務類,
????????focList.add(new?FileOutConfig("/templates/vm/exportservice.java.vm")?{
????????????@Override
????????????public?String?outputFile(TableInfo?tableInfo)?{
????????????????return?javaSrcDir+"/com/lzn/mybatisplus/codegenerator/export/"+tableInfo.getEntityName()+"ExportService.java";
????????????}
????????});
????????//生成mybatisDao文件到指定目錄
????????focList.add(new?FileOutConfig("/templates/vm/mybatisdao.java.vm")?{
????????????@Override
????????????public?String?outputFile(TableInfo?tableInfo)?{
????????????????return??javaSrcDir+"/com/lzn/mybatisplus/codegenerator/dao/"+tableInfo.getEntityName()+"MybatisDao.java";
????????????}
????????});
????????//生成mapper文件到指定目錄
????????focList.add(new?FileOutConfig("/templates/vm/mapper.xml.vm")?{
????????????@Override
????????????public?String?outputFile(TableInfo?tableInfo)?{
????????????????return?resourceDir+"/mybatis/"+tableInfo.getEntityName()+"Mapper.xml";
????????????}
????????});
????????//?自定義?xxList.ftl?生成
????????focList.add(new?FileOutConfig("/templates/vm/list.ftl.vm")?{
????????????@Override
????????????public?String?outputFile(TableInfo?tableInfo)?{
????????????????//?自定義輸入文件名稱
????????????????return?pageRootDir+pageDirName+"/list.ftl";
????????????}
????????});
????????cfg.setFileOutConfigList(focList);
????????mpg.setCfg(cfg);
????????//?關閉默認?xml?生成,調整生成?至?根目錄
????????TemplateConfig?tc?=?new?TemplateConfig();
????????tc.setEntity("/templates/vm/entity.java.vm");
????????tc.setService("/templates/vm/service.java.vm");
????????tc.setServiceImpl(null);//設成null才會不生產
????????tc.setController("/templates/vm/controller.java.vm");
????????tc.setMapper(null);
????????tc.setXml(null);
????????mpg.setTemplate(tc);
????????//?自定義模板配置,可以?copy?源碼?mybatis-plus/src/main/resources/templates?下面內容修改,
????????//?放置自己項目的?src/main/resources/templates?目錄下,?默認名稱一下可以不配置,也可以自定義模板名稱
????????//?TemplateConfig?tc?=?new?TemplateConfig();
????????//?tc.setController("...");
????????//?tc.setEntity("...");
????????//?tc.setMapper("...");
????????//?tc.setXml("...");
????????//?tc.setService("...");
????????//?tc.setServiceImpl("...");
????????//?如上任何一個模塊如果設置?空?OR?Null?將不生成該模塊。
????????//?mpg.setTemplate(tc);
????????//?執(zhí)行生成
????????mpg.execute();
????????//?打印注入設置【可無】
????????System.err.println(mpg.getCfg().getMap().get("abc"));
????}
}
執(zhí)行代碼生成器的Main方法

執(zhí)行代碼后,在對應的目錄自動生成了文件

啟動項目

并訪問列表頁路徑 http://localhost:8080/admin/goods/list


點擊導出按鈕(由于篇幅有限,導出的視圖對象,導出service類和aop切面實現(xiàn)本文沒有闡述,各位可自行下載代碼查看)


總結
本文為項目自動生成前后端代碼提供了思路:我們可以為項目的增刪改查業(yè)務編寫一套規(guī)范的代碼,以此編寫代碼模板,后續(xù)通過代碼生成器,通過數(shù)據(jù)庫的一張表可快速生成前后端代碼,提高項目組的開發(fā)效率。
代碼
https://github.com/pengziliu/GitHub-code-practice
這個項目包含很多輪子實例,每個實例都配有技術文章。
覺得不錯可以給個Star哦~

推薦實戰(zhàn)文章
Java實現(xiàn)圖片水印+壓縮So easy! 分布式定時任務xxJob的常用姿勢都集齊了,So Easy! 這個輪子讓SpringBoot實現(xiàn)api加密So Easy! 實戰(zhàn):SpringBoot集成xxl-sso實現(xiàn)單點登錄 神奇!不需要服務器,搭建免費個人Blog,so easy! 沒想到啊,Java操作Excel竟然這么簡單! 實戰(zhàn):Shardingsphere分庫分表 實戰(zhàn):十分鐘實現(xiàn)基于JWT前后端分離的權限框架 實戰(zhàn):SpringBoot集成rabbitmq并實現(xiàn)延時隊列 實戰(zhàn):SpringBoot分布式驗證碼登錄方案
原創(chuàng)不易,覺得有點用的話,請為本文點個在看,因為這將是我肝輪子的最強動力。
寫了幾十篇原創(chuàng)在這個小號,并行更新,關注回復“資料”有驚喜哦
