實戰:一鍵生成前後端程式碼,Mybatis-Plus程式碼生成器讓我舒服了

來碗java發表於2020-07-31

實戰:一鍵生成前後端程式碼,Mybatis-Plus程式碼生成器讓我舒服了

前言

在日常的軟體開發中,程式設計師往往需要花費大量的時間寫CRUD,不僅枯燥效率低,而且每個人的程式碼風格不統一。MyBatis-Plus 程式碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模組及前端頁面的程式碼,極大的提升了開發效率。

專案介紹

本專案將以springboot用演示,前端使用freemaker,資料庫持久層用mybatis(考慮到mybatis的使用還是最普遍的,就沒有用jpa和mybatisplus),通過Velocity模板引擎配置各模組的檔案模板,通過mybatis-plus程式碼生成器連線mysql,用商品表為例生成各模組的程式碼和前端頁面。(本專案只演示分頁查詢和匯出功能)。

本專案所有程式碼和指令碼都能都文末找到地址。

實戰

資料庫指令碼

建立一張商品表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 '商品狀態',
  `sale_count` int(11) DEFAULT NULL COMMENT '銷量',
  `create_date` datetime DEFAULT NULL COMMENT '建立時間',
  `modify_date` datetime DEFAULT NULL COMMENT '修改時間'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

maven依賴

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.1.4</version>
        </dependency>

        <!-- aspectj -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--es-->

        <!-- lombok 簡化get/set 方法 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
		<!--csv匯出用到-->
        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>3.8</version>
        </dependency>
		
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </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} 表示實體名,${field.name} 表示欄位名,我們在AutoGenerator程式碼生成器裡定義的全域性變數 ${author}、${date} 表示作者,日期等。在Velocity中用#表示語法,例如 #foreach($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;

/**
 * 資料庫表名 ${table.name}
 *
 * @author ${author}
 * @date ${date}
 */
@Getter
@Setter
@ToString
public class ${table.entityName}  {

    #foreach($field in ${table.fields})
    /**
     * 資料庫欄位名 ${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;

/**
 * <p>
 * ${tablecomment}  前端控制器
 * </p>
 *
 * @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<String,Object> 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.*;


/**
 * <p>
 * $!{tablecomment} 服務類
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Service
public class ${table.serviceName} {

    @Resource
    private ${table.mapperName} ${table.entityPath}Dao;

    /**
     * 分頁查詢
     * */
    public GridDataModel<${table.entityName}VO>  findByPage(Map<String, Object> 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}  {
    /**
     *  根據主鍵刪除資料庫的記錄, ${table.name}
     */
    int deleteByPrimaryKey(Long id);

    /**
     *  新寫入資料庫記錄, ${table.name}
     */
    int insert(${table.entityName} record);

    /**
     *  根據指定主鍵獲取一條資料庫記錄, ${table.name}
     */
    ${table.entityName} selectByPrimaryKey(Long id);

    /**
     *  根據主鍵來更新符合條件的資料庫記錄, ${table.name}
     */
    int updateByPrimaryKey(${table.entityName} record);

    /**
     *  根據條件分頁查詢
     * */
    List<${table.entityName}VO> listForPage(Map<String,Object> searchMap);

    /**
     *  根據條件分頁查詢(計數)
     * */
    long countForPage(Map<String,Object> searchMap);
    
}

Mapper.xml模板(mapper.xml.vm)

<?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="${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 <![CDATA[>=]]>  #{beginDate}
        </if>
        <if test="endDate != null and endDate != ''">
            and  create_date <![CDATA[<=]]> #{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 <![CDATA[>=]]>  #{beginDate}
        </if>
        <if test="endDate != null and endDate != ''">
            and  create_date <![CDATA[<=]]> #{endDate}
        </if>
        limit #{start}, #{limit}
    </select>
</mapper>

前端頁面list.ftl模板(list.ftl.vm)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <#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 : '建立時間', 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">狀態:</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">聯絡人:</span>
      <input type="text" class="input-text" name="filter_LIKES_name" />
      <span class="label">建立時間:</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;


/**
 * 輔助生產後臺開發相關程式碼  開發時只在自己原生程式碼修改,不要提交
 * 生成ddao service controller entity java程式碼 和前端 flt檔案。
 * 只演示list場景
 */
public class MpGenerator {

    //注意:開發時只在自己原生程式碼修改,不要提交、不要提交 不要提交
    //第一步修改 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 修改成你要開發的模組的名稱 存放ftl檔案的資料夾的根路徑
    static String pageRootDir ="D:/Git_space/lunzijihua/codegenerator/src/main/resources/templates/pages/";


    //第三步修改 packageName 修改成你要開發的模組的名稱 包名 要小寫 生產的entity service dao action資料夾和java程式碼會在下面
    static String packageName = "user";//模組資料夾包名稱
    //第四步修改 pageDirName 修改成你要開發的模組的名稱 存放ftl檔案的資料夾 要小寫
    static String pageDirName = "user";//模組頁面資料夾名
    //第五步驟 表的字首 填寫了 生成檔案時會去除掉
    static String tablePrefix="test_";
    //第六步 資料庫裡面對應的表的全名
    static String tableName="test_goods";

    /**
     * <p>
     * 程式碼自動生成
     * </p>
     */
    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);

        // 資料來源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);


        dsc.setTypeConvert(new MySqlTypeConvert(){
            // 自定義資料庫表欄位型別轉換【可選】
            @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 實現類父類
        // 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<String, Object> map = new HashMap<String, Object>();
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                map.put("pageDirName",pageDirName);
                map.put("packageName",packageName);
                this.setMap(map);
            }
        };

        List<FileOutConfig> focList = new ArrayList<FileOutConfig>();

//        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);

        // 執行生成
        mpg.execute();

        // 列印注入設定【可無】
        System.err.println(mpg.getCfg().getMap().get("abc"));
    }

}

執行程式碼生成器的Main方法

執行程式碼後,在對應的目錄自動生成了檔案

啟動專案

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

點選匯出按鈕(由於篇幅有限,匯出的檢視物件,匯出service類和aop切面實現本文沒有闡述,各位可自行下載程式碼檢視)

總結

本文為專案自動生成前後端程式碼提供了思路:我們可以為專案的增刪改查業務編寫一套規範的程式碼,以此編寫程式碼模板,後續通過程式碼生成器,通過資料庫的一張表可快速生成前後端程式碼,提高專案組的開發效率。

程式碼

https://github.com/pengziliu/GitHub-code-practice

相關文章