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的文件管理系统,可用于练手或者毕业设计