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

Posted 结构化思维wz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.简单!手撸一个基于Springboot的文件管理系统,可用于练手或者毕业设计

    简单!手撸一个基于Springboot的文件管理系统,可用于练手或者毕业设计

    手撸一个基于Springboot的文件管理系统,可用于练手或者毕业设计

    手撸一个基于Springboot的文件管理系统,可用于练手或者毕业设计

    手撸一个基于Springboot+Vue的书籍论坛系统,可用于课程设计和毕业设计或者练手

    手撸一个基于Springboot+Vue的书籍论坛系统,可用于课程设计和毕业设计或者练手