springboot+freemarker手撸一个代码自动生成器!!

手撸一个代码自动生成器!!

实现功能:MyBatis 逆向工程
springboot+freemarker手撸一个代码自动生成器!!_第1张图片

技术架构

页面是用 Vue ,element-ui开发;网络请求是 Axios。
服务端是 Spring Boot
页面模版是 Freemarker:

springboot+freemarker手撸一个代码自动生成器!!_第2张图片

开发步骤:

一、创建工程

springboot+freemarker手撸一个代码自动生成器!!_第3张图片

二、数据库连接操作

1.所需包结构

springboot+freemarker手撸一个代码自动生成器!!_第4张图片

2.在model包中创建Db类

作用:用于接受前端传来数据库连接相关的值(username,password,url)

package com.example.generate_code.model;

/**
 * @author: 王泽
 */

public class Db {
     
    private String username;
    private String password;
    private String url;


    public String getUsername() {
     
        return username;
    }

    public void setUsername(String username) {
     
        this.username = username;
    }

    public String getPassword() {
     
        return password;
    }

    public void setPassword(String password) {
     
        this.password = password;
    }

    public String getUrl() {
     
        return url;
    }

    public void setUrl(String url) {
     
        this.url = url;
    }
}

3.在model中创建RespBean类

自定义响应类,返回数据更方便

package com.example.generate_code.model;

/**
 * @author: 王泽
 */

public class RespBean {
     
    private Integer status;
    private String msg;
    private Object obj;

    public static RespBean ok(String msg,Object obj) {
     
        return new RespBean(200, msg, obj);
    }


    public static RespBean ok(String msg) {
     
        return new RespBean(200, msg, null);
    }


    public static RespBean error(String msg,Object obj) {
     
        return new RespBean(500, msg, obj);
    }


    public static RespBean error(String msg) {
     
        return new RespBean(500, msg, null);
    }

    private RespBean() {
     
    }

    private RespBean(Integer status, String msg, Object obj) {
     
        this.status = status;
        this.msg = msg;
        this.obj = obj;
    }

    public Integer getStatus() {
     
        return status;
    }

    public void setStatus(Integer status) {
     
        this.status = status;
    }

    public String getMsg() {
     
        return msg;
    }

    public void setMsg(String msg) {
     
        this.msg = msg;
    }

    public Object getObj() {
     
        return obj;
    }

    public void setObj(Object obj) {
     
        this.obj = obj;
    }


}

4.在Utils中创建DBUtils

JDBC连接工具类

public class DbUtils {
     
    private static Connection connection;

    public static Connection getConnection() {
     
        return connection;
    }

    public static Connection initDb(Db db) {
     
        if (connection == null) {
     
            try {
     
                Class.forName("com.mysql.cj.jdbc.Driver");
                connection = DriverManager.getConnection(db.getUrl(), db.getUsername(), db.getPassword());
            } catch (ClassNotFoundException | SQLException e) {
     
                e.printStackTrace();
            }
        }
        return connection;
    }


}

5.写一个连接接口DbController

连接数据库

@RestController
public class DbController {
     
    @PostMapping("/connect")
    public RespBean connect(@RequestBody Db db) {
     
        Connection con = DBUtils.initDb(db);
        if (con != null) {
     
            return RespBean.ok("数据库连接成功");
        }
        return RespBean.error("数据库连接失败");
    }
}

6.创建index页面


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>代码生成工具title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
    
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    
    <script src="https://unpkg.com/element-ui/lib/index.js">script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js">script>
head>
<body>
<div id="app">
    <table>
        <tr>
            <td>
                <el-tag size="mini">数据库用户名:el-tag>
            td>
            <td>
                <el-input size="mini" v-model="db.username">el-input>
            td>
        tr>
        <tr>
            <td>
                <el-tag size="mini">数据库密码:el-tag>
            td>
            <td>
                <el-input size="mini" v-model="db.password">el-input>
            td>
        tr>
        <tr>
            <td>
                <el-tag size="mini">数据库连接地址:el-tag>
            td>
            <td>
                <el-input size="mini" v-model="db.url">
                    <template slot="prepend">jdbc:mysql://template>
                    <template slot="append">
                        ?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
                    template>
                el-input>
            td>
        tr>
    table>
    <div style="display: flex">
        <el-button type="primary" size="mini" @click="connect" :disabled="!connectBtnEnabled">连接数据库el-button>
        <div style="color: #ff018d;font-weight: bold">[{
    {msg}}]div>
        <el-input v-model="packageName" size="mini" style="width: 300px">el-input>
        <el-button type="primary" size="mini" @click="config">配置el-button>
    div>
div>
<script>
    new Vue({
      
        el: "#app",
        data: function () {
      
            return {
      
                packageName: '',
                msg: '数据库未连接',
                connectBtnEnabled: true,
                db: {
      
                    username: "root",
                    password: "123456",
                    url: "localhost:3306/"
                }
            }
        },
        methods: {
      
           
            connect() {
      
                let _this = this;
                this.db.url = "jdbc:mysql://" + this.db.url + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
                axios.post('/connect', this.db)
                    .then(function (response) {
      
                        _this.msg = response.data.msg;
                        _this.db = {
      
                            username: "root",
                            password: "123456",
                            url: "localhost:3306/"
                        }
                        _this.connectBtnEnabled = false;
                    })
                    .catch(function (error) {
      
                        console.log(error);
                    });
            }
        }
    })
script>
body>
html>

springboot+freemarker手撸一个代码自动生成器!!_第5张图片

三、加载数据表信息

1.服务器端编写

  • ColumnClass 用来描述表中的每一列

    package com.example.generate_code.model;
    
    /**
     * @author: 王泽
     */
    
    public class ColumnClass {
           
        private String propertyName; //对应java属性的名字
        private String columnName;  //数据库中的名字
        private String type;        //字段类型
        private String remark;      //备注
        private Boolean isPrimary;  //字段是不是一个主键
    
        @Override
        public String toString() {
           
            return "ColumnClass{" +
                    "propertyName='" + propertyName + '\'' +
                    ", columnName='" + columnName + '\'' +
                    ", type='" + type + '\'' +
                    ", remark='" + remark + '\'' +
                    ", isPrimary=" + isPrimary +
                    '}';
        }
    
        public String getPropertyName() {
           
            return propertyName;
        }
    
        public void setPropertyName(String propertyName) {
           
            this.propertyName = propertyName;
        }
    
        public String getColumnName() {
           
            return columnName;
        }
    
        public void setColumnName(String columnName) {
           
            this.columnName = columnName;
        }
    
        public String getType() {
           
            return type;
        }
    
        public void setType(String type) {
           
            this.type = type;
        }
    
        public String getRemark() {
           
            return remark;
        }
    
        public void setRemark(String remark) {
           
            this.remark = remark;
        }
    
        public Boolean getPrimary() {
           
            return isPrimary;
        }
    
        public void setPrimary(Boolean primary) {
           
            isPrimary = primary;
        }
    
    
    }
    
    
  • 描述一个具体的表的信息 TableClass

    package com.example.generate_code.model;
    
    import java.util.List;
    
    /**
     * @author: 王泽
     */
    
    public class TableClass {
           
        private String tableName;  //表名 ,以下是生成的名字
        private String modelName;
        private String serviceName;
        private String mapperName;
        private String controllerName;
        private String packageName;
        private List<ColumnClass> columns; // 字段
    
        @Override
        public String toString() {
           
            return "TableClass{" +
                    "tableName='" + tableName + '\'' +
                    ", modelName='" + modelName + '\'' +
                    ", serviceName='" + serviceName + '\'' +
                    ", mapperName='" + mapperName + '\'' +
                    ", controllerName='" + controllerName + '\'' +
                    ", packageName='" + packageName + '\'' +
                    ", columns=" + columns +
                    '}';
        }
    
        public String getTableName() {
           
            return tableName;
        }
    
        public void setTableName(String tableName) {
           
            this.tableName = tableName;
        }
    
        public String getModelName() {
           
            return modelName;
        }
    
        public void setModelName(String modelName) {
           
            this.modelName = modelName;
        }
    
        public String getServiceName() {
           
            return serviceName;
        }
    
        public void setServiceName(String serviceName) {
           
            this.serviceName = serviceName;
        }
    
        public String getMapperName() {
           
            return mapperName;
        }
    
        public void setMapperName(String mapperName) {
           
            this.mapperName = mapperName;
        }
    
        public String getControllerName() {
           
            return controllerName;
        }
    
        public void setControllerName(String controllerName) {
           
            this.controllerName = controllerName;
        }
    
        public String getPackageName() {
           
            return packageName;
        }
    
        public void setPackageName(String packageName) {
           
            this.packageName = packageName;
        }
    
        public List<ColumnClass> getColumns() {
           
            return columns;
        }
    
        public void setColumns(List<ColumnClass> columns) {
           
            this.columns = columns;
        }
    
    }
    
    

    创建配置接口Controller

    用map来接受前端传来的数据

    用到了谷歌提供的工具包guava,需要导入依赖

     @PostMapping("/config")
        public RespBean config(@RequestBody Map<String, String> map) {
           
            String packageName = map.get("packageName");
            try {
           
                Connection connection = DBUtils.getConnection();
                DatabaseMetaData metaData = connection.getMetaData();
                ResultSet tables = metaData.getTables(connection.getCatalog(), null, null, null);
                List<TableClass> tableClassList = new ArrayList<>();
                while (tables.next()) {
           
                    TableClass tableClass = new TableClass();
                    tableClass.setPackageName(packageName);
                    String table_name = tables.getString("TABLE_NAME");
                    String modelName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table_name);
                    tableClass.setTableName(table_name);
                    tableClass.setModelName(modelName);
                    tableClass.setControllerName(modelName + "Controller");
                    tableClass.setMapperName(modelName + "Mapper");
                    tableClass.setServiceName(modelName+"Service");
                    tableClassList.add(tableClass);
                }
                return RespBean.ok("数据库信息读取成功", tableClassList);
            } catch (Exception e) {
           
                e.printStackTrace();
            }
            return RespBean.error("数据库信息读取失败");
        }
    
    <dependency>
                <groupId>com.google.guavagroupId>
                <artifactId>guavaartifactId>
                <version>30.1-jreversion>
            dependency>
    

2.完善index页面


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>代码生成工具title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
    
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    
    <script src="https://unpkg.com/element-ui/lib/index.js">script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js">script>
head>
<body>
<div id="app">
    <table>
        <tr>
            <td>
                <el-tag size="mini">数据库用户名:el-tag>
            td>
            <td>
                <el-input size="mini" v-model="db.username">el-input>
            td>
        tr>
        <tr>
            <td>
                <el-tag size="mini">数据库密码:el-tag>
            td>
            <td>
                <el-input size="mini" v-model="db.password">el-input>
            td>
        tr>
        <tr>
            <td>
                <el-tag size="mini">数据库连接地址:el-tag>
            td>
            <td>
                <el-input size="mini" v-model="db.url">
                    <template slot="prepend">jdbc:mysql://template>
                    <template slot="append">
                        ?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
                    template>
                el-input>
            td>
        tr>
    table>
    <div style="display: flex">
        <el-button type="primary" size="mini" @click="connect" :disabled="!connectBtnEnabled">连接数据库el-button>
        <div style="color: #ff018d;font-weight: bold">[{
    {msg}}]div>
        <el-input v-model="packageName" size="mini" style="width: 300px">el-input>
        <el-button type="primary" size="mini" @click="config">配置el-button>
    div>
    <el-table
            :data="tableData"
            stripe
            border
            style="width: 100%">
        <el-table-column
                prop="tableName"
                label="表名称"
                width="180">
        el-table-column>
        <el-table-column
                label="实体类名称"
                width="180">
            <template slot-scope="scope">
                <el-input v-model="scope.row.modelName">el-input>
            template>
        el-table-column>
        <el-table-column
                label="Mapper名称">
            <template slot-scope="scope">
                <el-input v-model="scope.row.mapperName">el-input>
            template>
        el-table-column>
        <el-table-column
                label="Service名称">
            <template slot-scope="scope">
                <el-input v-model="scope.row.serviceName">el-input>
            template>
        el-table-column>
        <el-table-column
                label="Controller名称">
            <template slot-scope="scope">
                <el-input v-model="scope.row.controllerName">el-input>
            template>
        el-table-column>
    el-table>
    <div>
        <el-button @click="generateCode" type="success">生成代码el-button>
        <div style="color: #ff0114;font-weight: bold">*{
    {result}}*div>
        <div>{
    {codePath}}div>
    div>
div>
<script>
    new Vue({
      
        el: "#app",
        data: function () {
      
            return {
      
                tableData: [],
                packageName: 'com.wangze.test',
                msg: '数据库未连接',
                connectBtnEnabled: true,
                db: {
      
                    username: "root",
                    password: "123456",
                    url: "localhost:3306/"
                }
            }
        },
        methods: {
      
            generateCode() {
      
                let _this = this;
                axios.post('/generateCode', this.tableData)
                    .then(function (response) {
      
                        _this.result = response.data.msg;
                        _this.codePath = response.data.obj;
                    })
                    .catch(function (error) {
      
                    });
            },
            config() {
      
                let _this = this;
                axios.post('/config', {
      packageName: this.packageName})
                    .then(function (response) {
      
                        _this.msg = response.data.msg;
                        _this.tableData = response.data.obj;
                    })
                    .catch(function (error) {
      
                        console.log(error);
                    });
            },
            connect() {
      
                let _this = this;
                this.db.url = "jdbc:mysql://" + this.db.url + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
                axios.post('/connect', this.db)
                    .then(function (response) {
      
                        _this.msg = response.data.msg;
                        _this.db = {
      
                            username: "root",
                            password: "123456",
                            url: "localhost:3306/"
                        }
                        _this.connectBtnEnabled = false;
                    })
                    .catch(function (error) {
      
                        console.log(error);
                    });
            }
        }
    })
script>
body>
html>

springboot+freemarker手撸一个代码自动生成器!!_第6张图片

四、代码生成

1.创建模板

  • Model.java.ftl

package ${
     packageName}.model;

import java.util.Date;

public class ${
     modelName}{
     

    <#if columns??>
        <#list columns as column>
            <#if column.type='VARCHAR'||column.type='TEXT'||column.type='CHAR'>
                /**
                * ${column.remark}
                */
                private String ${
     column.propertyName?uncap_first};
            </#if>
            <#if column.type='INT'>
                /**
                * ${column.remark}
                */
                private Integer ${
     column.propertyName?uncap_first};
            </#if>
            <#if column.type='DATETIME'>
                /**
                * ${column.remark}
                */
                private Date ${
     column.propertyName?uncap_first};
            </#if>
            <#if column.type='BIGINT'>
                /**
                * ${column.remark}
                */
                private Long ${
     column.propertyName?uncap_first};
            </#if>
            <#if column.type='DOUBLE'>
                /**
                * ${column.remark}
                */
                private Double ${
     column.propertyName?uncap_first};
            </#if>
            <#if column.type='BIT'>
                /**
                * ${column.remark}
                */
                private Boolean ${
     column.propertyName?uncap_first};
            </#if>
        </#list>
    </#if>
    <#if columns??>
        <#list columns as column>
            <#if column.type='VARCHAR'||column.type='TEXT'||column.type='CHAR'>
                public String get${
     column.propertyName}(){
     
                    return ${
     column.propertyName?uncap_first};
                }
                public void set${
     column.propertyName}(String ${
     column.propertyName?uncap_first}){
     
                    this.${
     column.propertyName?uncap_first}=${
     column.propertyName?uncap_first};
                }
            </#if>
            <#if column.type='INT'>
                public Integer get${
     column.propertyName}(){
     
                return ${
     column.propertyName?uncap_first};
                }
                public void set${
     column.propertyName}(Integer ${
     column.propertyName?uncap_first}){
     
                this.${
     column.propertyName?uncap_first}=${
     column.propertyName?uncap_first};
                }
            </#if>
            <#if column.type='DATETIME'>
                public Date get${
     column.propertyName}(){
     
                return ${
     column.propertyName?uncap_first};
                }
                public void set${
     column.propertyName}(Date ${
     column.propertyName?uncap_first}){
     
                this.${
     column.propertyName?uncap_first}=${
     column.propertyName?uncap_first};
                }
            </#if>
            <#if column.type='BIGINT'>
                public Long get${
     column.propertyName}(){
     
                return ${
     column.propertyName?uncap_first};
                }
                public void set${
     column.propertyName}(Long ${
     column.propertyName?uncap_first}){
     
                this.${
     column.propertyName?uncap_first}=${
     column.propertyName?uncap_first};
                }
            </#if>
            <#if column.type='DOUBLE'>
                public Double get${
     column.propertyName}(){
     
                return ${
     column.propertyName?uncap_first};
                }
                public void set${
     column.propertyName}(Double ${
     column.propertyName?uncap_first}){
     
                this.${
     column.propertyName?uncap_first}=${
     column.propertyName?uncap_first};
                }
            </#if>
            <#if column.type='BIT'>
                public Boolean get${
     column.propertyName}(){
     
                return ${
     column.propertyName?uncap_first};
                }
                public void set${
     column.propertyName}(Boolean ${
     column.propertyName?uncap_first}){
     
                this.${
     column.propertyName?uncap_first}=${
     column.propertyName?uncap_first};
                }
            </#if>
        </#list>
    </#if>
}
  • Service.java.ftl

    package ${
           packageName}.service;
    
    import ${
           packageName}.model.${
           modelName};
    import ${
           packageName}.mapper.${
           mapperName};
    import org.springframework.stereotype.Service;
    import org.springframework.beans.factory.annotation.Autowired;
    import java.util.List;
    
    @Service
    public class ${
           serviceName}{
           
    
        @Autowired
        ${
           mapperName} ${
           mapperName?uncap_first};
        public List<${
           modelName}> getAll${
           modelName}s(){
           
            return ${
           mapperName?uncap_first}.getAll${
           modelName}s();
        }
    }
    
  • Controller.java.ftl

    package ${
           packageName}.controller;
    
    import ${
           packageName}.model.${
           modelName};
    import ${
           packageName}.service.${
           serviceName};
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.bind.annotation.GetMapping;
    import java.util.List;
    
    @RestController
    public class ${
           controllerName}{
           
    
        @Autowired
        ${
           serviceName} ${
           serviceName?uncap_first};
    
        @GetMapping("/${modelName?lower_case}s")
        public List<${
           modelName}> getAll${
           modelName}s(){
           
            return ${
           serviceName?uncap_first}.getAll${
           modelName}s();
        }
    }
    
  • Mapper.java.ftl

    package ${
           packageName}.mapper;
    
    import ${
           packageName}.model.${
           modelName};
    import org.apache.ibatis.annotations.Mapper;
    import java.util.List;
    
    @Mapper
    public interface ${
           mapperName}{
           
        List<${
           modelName}> getAll${
           modelName}s();
    }
    
  • Mapper.xml.ftl

    
    <mapper namespace="${packageName}.mapper.${mapperName}">
    
        <resultMap id="BaseResultMap" type="${packageName}.model.${modelName}">
            <#list columns as column>
                <<#if column.primary??>id<#else>result#if> column="${column.columnName}" property="${column.propertyName?uncap_first}" jdbcType="<#if column.type='INT'>INTEGER<#elseif column.type='DATETIME'>TIMESTAMP<#elseif column.type='TEXT'>VARCHAR<#else>${column.type}#if>" />
            #list>
        resultMap>
    
        <select id="getAll${modelName}s" resultMap="BaseResultMap">
            select * from ${tableName};
        select>
    mapper>
    

2.代码生成Controller

package com.example.generate_code.controller;
import com.example.generate_code.model.RespBean;
import com.example.generate_code.model.TableClass;
import com.example.generate_code.service.GenerateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
public class GenerateCodeController {
     
    @Autowired
    GenerateCodeService generateCodeService;


    @PostMapping("/generateCode")
    public RespBean generateCode(@RequestBody List<TableClass> tableClassList, HttpServletRequest req) {
     
        return generateCodeService.generateCode(tableClassList, req.getServletContext().getRealPath("/"));
    }
}

3.编写service

package com.example.generate_code.service;

import com.example.generate_code.model.ColumnClass;
import com.example.generate_code.model.RespBean;
import com.example.generate_code.model.TableClass;
import com.example.generate_code.utils.DBUtils;
import com.google.common.base.CaseFormat;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;


@Service
public class GenerateCodeService {
     

    Configuration cfg = null;

    {
     
        cfg = new Configuration(Configuration.VERSION_2_3_30);
        cfg.setTemplateLoader(new ClassTemplateLoader(GenerateCodeService.class, "/templates"));
        cfg.setDefaultEncoding("UTF-8");
    }

    public RespBean generateCode(List<TableClass> tableClassList, String realPath) {
     
        try {
     
            Template modelTemplate = cfg.getTemplate("Model.java.ftl");
            Template mapperJavaTemplate = cfg.getTemplate("Mapper.java.ftl");
            Template mapperXmlTemplate = cfg.getTemplate("Mapper.xml.ftl");
            Template serviceTemplate = cfg.getTemplate("Service.java.ftl");
            Template controllerTemplate = cfg.getTemplate("Controller.java.ftl");
            Connection connection = DBUtils.getConnection();
            DatabaseMetaData metaData = connection.getMetaData();
            for (TableClass tableClass : tableClassList) {
     
                ResultSet columns = metaData.getColumns(connection.getCatalog(), null, tableClass.getTableName(), null);
                ResultSet primaryKeys = metaData.getPrimaryKeys(connection.getCatalog(), null, tableClass.getTableName());
                List<ColumnClass> columnClassList = new ArrayList<>();
                while (columns.next()) {
     
                    String column_name = columns.getString("COLUMN_NAME");
                    String type_name = columns.getString("TYPE_NAME");
                    String remarks = columns.getString("REMARKS");
                    ColumnClass columnClass = new ColumnClass();
                    columnClass.setRemark(remarks);
                    columnClass.setColumnName(column_name);
                    columnClass.setType(type_name);
                    columnClass.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, column_name));
                    primaryKeys.first();
                    while (primaryKeys.next()) {
     
                        String pkName = primaryKeys.getString("COLUMN_NAME");
                        if (column_name.equals(pkName)) {
     
                            columnClass.setPrimary(true);
                        }
                    }
                    columnClassList.add(columnClass);
                }
                tableClass.setColumns(columnClassList);
                String path = realPath + "/" + tableClass.getPackageName().replace(".", "/");
                generate(modelTemplate, tableClass, path + "/model/");
                generate(mapperJavaTemplate, tableClass, path + "/mapper/");
                generate(mapperXmlTemplate, tableClass, path + "/mapper/");
                generate(serviceTemplate, tableClass, path + "/service/");
                generate(controllerTemplate, tableClass, path + "/controller/");
            }
            return RespBean.ok("代码已生成", realPath);
        } catch (Exception e) {
     
            e.printStackTrace();
        }
        return RespBean.error("代码生成失败");
    }

    private void generate(Template template, TableClass tableClass, String path) throws IOException, TemplateException {
     
        File folder = new File(path);
        if (!folder.exists()) {
     
            folder.mkdirs();
        }
        String fileName = path + "/" + tableClass.getModelName() + template.getName().replace(".ftl", "").replace("Model", "");
        FileOutputStream fos = new FileOutputStream(fileName);
        OutputStreamWriter out = new OutputStreamWriter(fos);
        template.process(tableClass,out);
        fos.close();
        out.close();
    }
}

五、测试

springboot+freemarker手撸一个代码自动生成器!!_第7张图片

springboot+freemarker手撸一个代码自动生成器!!_第8张图片

这时候已经找到了,我们来验证一下效果!

springboot+freemarker手撸一个代码自动生成器!!_第9张图片

  • 修改写配置

    spring.datasource.name=root
    spring.datasource.password=123456
    spring.datasource.url=jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    
    
  • pom.xml

    <resources>
                <resource>
                    <directory>src/main/javadirectory>
                    <includes>
                        <include>**/*.xmlinclude>
                    includes>
                resource>
                <resource>
                    <directory>src/main/resourcesdirectory>
                resource>
            resources>
    
  • 导入生成的代码

springboot+freemarker手撸一个代码自动生成器!!_第10张图片

  • 运行测试

一个基本的mybatis逆向工程就完成了!

最后附上项目源代码:Gitee

还不快点赞吗????收藏???装bei????
springboot+freemarker手撸一个代码自动生成器!!_第11张图片

你可能感兴趣的:(项目,新星计划,springboot,代码生成器,vue,freemarker)