springboot整合freemarker代码自动生成器

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

实现功能:MyBatis 逆向工程

技术架构

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

开发步骤:

一、创建工程

二、数据库连接操作

1.所需包结构

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页面

<!DOCTYPE html>
<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>

三、加载数据表信息

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.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1-jre</version>
        </dependency>

2.完善index页面

<!DOCTYPE html>
<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>

四、代码生成

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

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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();
    }
}

五、测试

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

修改写配置

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/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>

导入生成的代码

运行测试

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

最后附上项目源代码:Gitee

到此这篇关于springboot整合freemarker代码自动生成器的文章就介绍到这了,更多相关springboot 代码自动生成器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot 通过代码自动生成pid的方法

    springboot项目部署 平时我们在部署springboot打成jar方式部署得时候,大多数都会编写启动脚本,脚本有很多种写法,但大多数意思都是一样的,java -jar 启动项目,获取进程pid保存到指定文件中.关闭程序时,获取进程pid kill -9 $pid.获取pid有很多种写法,简答粗暴netstat -nlp port | grep port | grep -v .其实springboot本身就有更简单方式来处理这种问题,两行代码就搞定. @SpringBootApplicat

  • SpringBoot整合screw实现数据库文档自动生成的示例代码

    有时候数据库文档需要整理,可是只能手动的复制粘贴,心中一万只草泥马奔腾而过... screw 简洁好用的数据库表结构文档生成工具. 1. 创建项目 1.1 pom.xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>

  • SpringBoot基于Mybatis-Plus自动代码生成

    前言 大家好啊,我是汤圆,今天给大家带来的是<SpringBoot中的自动代码生成 - 基于Mybatis-Plus>,希望对大家有帮助,谢谢 简介 基于Mybatis-Plus的自动代码生成有很多方式,这里介绍下我在用的两种: 本地代码生成:Mybatis-Plus官方 在线代码生成:第三方 这两种各有优缺点,看喜欢哪一种了 听说Idea也有自动生成的插件,但是我还没去看,我觉得这俩就够用了(但也说不准哪天,用了插件后,才发现柳暗花明呢) 有的官人,可能要问了,既然Mybatis-Plus官

  • springboot整合freemarker代码自动生成器

    手撸一个代码自动生成器!! 实现功能:MyBatis 逆向工程 技术架构 页面是用 Vue ,element-ui开发:网络请求是 Axios. 服务端是 Spring Boot 页面模版是 Freemarker: 开发步骤: 一.创建工程 二.数据库连接操作 1.所需包结构 2.在model包中创建Db类 作用:用于接受前端传来数据库连接相关的值(username,password,url) package com.example.generate_code.model; /** * @aut

  • springboot 整合 freemarker代码实例

    这篇文章主要介绍了springboot 整合 freemarker代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE&l

  • SpringBoot整合Mybatis Generator自动生成代码

    目录 1.创建SpringBoot项目 2. mybatis-generator-maven插件的配置 3. 项目结构构建 4. application.yml配置 5. generatorConfig.xml配置 7. 选择 Mybatis Generator 启动,自动在dao.entity.mapper包下生成代码 Mybatis是目前主流的ORM框架,相比于hibernate的全自动,它是半自动化需要手写sql语句.接口.实体对象,后来推出的Generator自动生成代码,可以帮我们提高

  • SpringBoot整合freemarker实现代码生成器

    目录 一.介绍 二.代码实践 2.1.首先我们添加 freemarker 依赖包 2.2.然后创建一个代码模版 2.3.最后生成目标代码 三.小结 一.介绍 在实际的软件项目开发过程中,我可以很负责任的跟大家说,如果你真的实际写代码的时间超过5年,你对增删改查这类简单的功能需求开发,可以说已经完全写吐了,至少我就是这种类型的. 但是呢,不可否认,绝大多数的软件功能,向下追随到最基本的单元,也基本都是单表的增.删.改.查! 只是随着用户需求不断增多,原来可能一个张单表就可以搞定的事情,现在可能需要

  • springboot整合freemarker的踩坑及解决

    目录 springboot整合freemarker踩坑 报错 问题原因 解决方法 springboot freemarker基础配置及使用 1.基础配置 2.基础使用 springboot整合freemarker踩坑 报错 2021-04-23 02:01:18.148 ERROR 9484 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatc

  • 基于mybatis-plus-generator实现代码自动生成器

    目录 1.引入依赖 2.简单的代码生成 3.自定义模板生成代码 3.1实现思路 3.2定义代码生成常量 3.3全局配置 3.4定义生成代码模板的路径 3.5定义各文件生成存储路径 3.6数据源配置 3.7配置策略 3.8组装模板属性 3.9定义对应的模板文件 3.10定义启动类 1.引入依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</

  • SpringBoot整合Freemarker实现页面静态化的详细步骤

    第一步:创建项目添加依赖: <!--web和actuator(图形监控用)基本上都是一起出现的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.spri

  • SpringBoot整合freemarker的讲解

    freemarker和thymeleaf是模板引擎.在早前我们使用Struts或者SpringMVC等框架的时候,使用的都是jsp,jsp的本质其实就是一个Servlet,其中的数据需要在后端进行渲染,然后再在客户端显示,效率比较低下.而模板引擎恰恰相反,其中的数据渲染是在客户端,效率方面比较理想一点.前后端不分离的话用模板引擎比较好,前后端分离的话其实用处并不大很大.Spring官方比较推荐的是thymeleaf,其文件后缀是html.本篇文章我们主要来看看SpringBoot整合freema

  • springboot整合httpClient代码实例

    这篇文章主要介绍了springboot整合httpClient代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 创建httpClientConfig配置类 @Configuration @PropertySource(value="classpath:/properties/httpClient.properties") public class HttpClientConfig { @Value("${http.ma

  • Springboot整合Freemarker的实现详细过程

    基本配置.测试 1.导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> 2.准备一个Freemarker模板(.ftl) 3.注入Configuration对象(freemarker.template包下) 4.生成商品详情模

随机推荐