思路分析
我们可以认为代码生成器是收集一些信息后讲信息渲染到固定的代码模板中生成最终代码
准备知识
通过上面的分析,我们知道要写一个代码生成器要有以下一些预备知识:
- 可以获取用户输入
- 可以获取数据库信息
- 可以将内存信息写入到本地文件
上面的这几点几乎所有流行的编程语言都可以做得到。我们这里选择使用nodeJs
express
ejs
mysql
关键步骤代码
-
安装Express 应用程序生成器
# 如果安装缓慢请使用 cnpm https://www.oschina.net/p/cnpm?hmsr=aladdin1e1 npm install -g express-generator # 高版本node(包含在 Node.js 8.2.0 及更高版本中)可以用下面命令安装 npx express-generator
-
生成Express 基本框架
# 生成项目文件夹 mkdir gen cd gen # 生成Express框架 express -e --git
-
安装依赖包
# mysql 用来操作数据库 lodash 是一个JavaScript常用的工具包 npm install --save lodash mysql
-
创建基本信息收集表单
打开前面通过命令生成的Express项目文件夹,打开项目根目录下的
app.js
文件// 代码的12 - 14左右 // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs');
可以看到ejs模板目录是项目根目录下的
views
文件夹,在index.ejs
中添加一个表单,如下代码<!DOCTYPE html> <html> <head> <title>速聚代码生成器</title> <link rel='stylesheet' href='/lib/bootstrap-4.6.0/css/bootstrap.min.css'/> <link rel='stylesheet' href='/stylesheets/style.css'/> </head> <body> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="#">速聚代码生成器</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> <a class="nav-link" href="#">生成代码 <span class="sr-only">(current)</span></a> </li> </ul> </div> </nav> <div class="row" style="margin:30px auto;width:600px "> <form action="/tables" method="post"> <div class="form-group"> <label for="exampleInputEmail1">项目名称</label> <input type="name" class="form-control"> </div> <div class="form-group"> <label for="exampleInputPassword1">作者</label> <input class="form-control" name="author"> </div> <div class="form-group"> <label for="exampleInputPassword1">表前缀移除</label> <input class="form-control" name="pre"> </div> <div class="form-group"> <label for="exampleInputPassword1">生成文件</label> <br/> <span>后端: </span> <label><input type="checkbox" name="files[]" value="mappper">mappper</label> <label><input type="checkbox" name="files[]" value="mappperXML">mappperXML</label> <label><input type="checkbox" name="files[]" value="entity">entity</label> <label><input type="checkbox" name="files[]" value="param">param</label> <label><input type="checkbox" name="files[]" value="result">result</label> <label><input type="checkbox" name="files[]" value="controller">controller</label> <label><input type="checkbox" name="files[]" value="service">service</label> <label><input type="checkbox" name="files[]" value="serviceimpl">serviceimpl</label> <label><input type="checkbox" name="files[]" value="enum">enum</label> <br/> <span>前端: </span> <label><input type="checkbox" name="files[]" value="indexJsx">indexJsx</label> <label><input type="checkbox" name="files[]" value="addJsx">addJsx</label> <label><input type="checkbox" name="files[]" value="editJsx">editJsx</label> <label><input type="checkbox" name="files[]" value="apiJs">apiJs</label> </div> <div class="form-group"> <label for="exampleInputPassword1">是否生成api文档</label> <br/> <label><input type="radio" name="api">是</label> <label><input type="radio" name="api">否</label> </div> <button type="submit" class="btn btn-primary">下一步</button> </form> </div> </body> </html>
-
创建接收表单信息路由
Express 的路由文件写在项目根目录下的
routes
文件夹下,我们在routes/index.js
添加一个新的路由用来接收表单信息Express基本路由
router.post('/tables', function (req, res) { // req 就数据请求对象 });
-
创建数据库连接池
在获取到用户提交的信息之后我们还需要拿到数据库中的信息。
# 在项目根目录下创建一个配置文件夹 用来存放配置文件 mkdir config
在config文件夹中创建一个db.js的文件用来配置数据库信息和创建数据库连接池
var mysql = require('mysql') var pool = mysql.createPool({ connectionLimit: 10, host: '127.0.0.1', user: 'root', password: '', database: 'database' }); function query(sql, values, callback) { console.log("db pool"); pool.getConnection(function (err, connection) { if(err) throw err; console.log("sql ",sql,values); //Use the connection connection.query(sql, values,function (err, results, fields) { console.log(JSON.stringify(results),err); //每次查询都会 回调 callback(err, results); //只是释放链接,在缓冲池了,没有被销毁 connection.release(); if(err) throw error; }); }); } exports.query = query;
-
获取指定库中所有的表信息
通过上述创建的数据库连接池就能从数据库中读信息啦,我们回到
routes/index.js
文件// 引入数据库 const db = require("../config/db") .... /** * 获取数据库中所有的数据表信息 */ router.post('/tables', function (req, res) { /** * 简单思路 * 1. 通过 req.body 得到上一步中提交过来的信息 * 2. 通过查询数据库得到目前连接的数据库的表信息 */ db.query("show tables", [], function (err, rows) { res.render('index', { postData: {...req.body}, tables }); }); });
-
获取指定表中所有的字段信息
同样的方法我们可以新建一个路由用来获取指定表的所有字段信息
/** * 通过表名返回表结构信息 */ router.get('/table_info', function (req, res) { db.query('show full fields from' + req.query.name, [], function (err, rows) { res.send(rows); }); });
-
汇总数据库信息和表单信息渲染到模板
router.post('/gen', function (req, res) { // let dir = tempRootPath + new Date().getTime() + "/" let dir = tempRootPath const {tableColumn, postData} = req.body // 循环所有表 _.each(tableColumn, function (item, key) { // 帕斯卡表名 let pskTableName = _.capitalize(key) let frontPath = dir + key + "/front/" + pskTableName + "/" // 生成前端部分 按照表名称生成组件用帕斯卡方式 mkdirsSync(frontPath) // 用到的值直接结构以免出现bug const {author, pre} = postData /* * 根据文件结构配置模板,生成对应的数据 */ let allColumns = tableColumn[key] ? tableColumn[key] : [] // 生成代码 generate(frontTemplateFiles, frontPath, { updateColumns: _.filter(allColumns, item => item.showUpdate), updateMustColumns: _.filter(allColumns, item => item.mustUpdate), addColumns: _.filter(allColumns, item => item.showAdd), addMustColumns: _.filter(allColumns, item => item.mustAdd), listColumns: _.filter(allColumns, item => item.showList), searchColumns: _.filter(allColumns, item => item.isSearch), allColumns, author, pre, pskTableName }) }) res.send("ok") })
代码地址
github地址
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!