使用freemarker实现代码生成的小项目|后端代码生成篇
前言
使用freemarker来生成代码,先定义代码的模板,使用定义的模板和传入的模型变量来生成相应的代码。
源码地址:https://github.com/lizhongxiang12138/code-main.git
下一篇是 使用freemarker实现代码生成的小项目|前端代码篇
先看效果
项目结构
├─.idea
│ └─libraries
├─.mvn
│ └─wrapper
├─code-generation 代码生成业务模块
├─code-generation-template 代码模板模块
├─code-generation-ui 代码生成UI模块
└─common
代码模板模块(code-generation-template)
代码模板模块用来定义代码的模板
模块结构
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─lzx
│ │ │ └─code
│ │ │ └─codegenerationtemplate
│ │ │ │ CodeGenerationTemplateApplication.java
│ │ │ │
│ │ │ └─template
│ │ │ Controller.ftl api接口类模板
│ │ │ Dao.ftl DAO模板
│ │ │ EntityTemple.ftl 实体类模板
│ │ │ Service.ftl 业务接口类模板
│ │ │ ServiceImpl.ftl 业务实现类模板
│ │ │ TemplateUtils.java 模板工具类
│ │ │
│ │ └─resources
│ │ application.yml
│ │
│ └─test
│ └─java
│ └─com
│ └─lzx
│ └─code
│ └─codegenerationtemplate
│ │ CodeGenerationTemplateApplicationTests.java
│ │
│ └─template
│ TemplateUtilsTest.java
代码生成业务模块(code-generation)
代码生成业务模块提供生成代码的功能
模块结构
│ .gitignore
│ code-generation.iml
│ HELP.md
│ mvnw
│ mvnw.cmd
│ pom.xml
│
├─.mvn
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─lzx
│ │ │ └─code
│ │ │ └─codegeneration
│ │ │ │ CodeGenerationApplication.java
│ │ │ │
│ │ │ ├─config
│ │ │ │ CorsFilter.java 过滤器,对跨域的支持
│ │ │ │
│ │ │ ├─controller
│ │ │ │ CodeGenerationController.java 代码生成的api接口
│ │ │ │
│ │ │ ├─entity
│ │ │ │ ClassBean.java 代码生成的模型定义1
│ │ │ │ ClassBeanField.java 代码生成的模型定义2
│ │ │ │
│ │ │ ├─service
│ │ │ │ │ CodeGenerationService.java 代码生成功能业务接口
│ │ │ │ │
│ │ │ │ └─impl
│ │ │ │ CodeGenerationServiceImpl.java 代码生成功能业务实现
│ │ │ │
│ │ │ └─vo
│ │ │ DataTypeVO.java
│ │ │
│ │ └─resources
│ │ application.yml
主要业务代码
package com.lzx.code.codegeneration.service.impl;
import com.lzx.code.codegeneration.entity.ClassBean;
import com.lzx.code.codegeneration.service.CodeGenerationService;
import com.lzx.code.codegenerationtemplate.template.TemplateUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.StringWriter;
/**
* 描述: 代码服务生成业务实现
*
* @Auther: lzx
* @Date: 2019/7/18 13:10
*/
@Service
@Slf4j
public class CodeGenerationServiceImpl implements CodeGenerationService {
private Configuration cfg;
public CodeGenerationServiceImpl() throws IOException {
cfg = TemplateUtils.getConfiguration();
}
/**
* 生成实体类
* @param classBean
* @return
*/
@Override
public String generationEntiry(ClassBean classBean) throws IOException, TemplateException {
Template template = cfg.getTemplate("EntityTemple.ftl", "UTF-8");
//输出
StringWriter out = new StringWriter();
template.process(classBean,out);
return out.toString();
}
@Override
public String generationDao(ClassBean classBean) throws IOException, TemplateException {
Template template = cfg.getTemplate("Dao.ftl", "UTF-8");
//输出
StringWriter out = new StringWriter();
template.process(classBean,out);
return out.toString();
}
/**
* 生成业务接口代码
* @param classBean
* @return
*/
@Override
public String generationService(ClassBean classBean) throws IOException, TemplateException {
Template template = cfg.getTemplate("Service.ftl", "UTF-8");
//输出
StringWriter out = new StringWriter();
template.process(classBean,out);
return out.toString();
}
/**
* 生成业务的实现
* @param classBean
* @return
*/
@Override
public String generationServiceImpl(ClassBean classBean) throws IOException, TemplateException {
Template template = cfg.getTemplate("ServiceImpl.ftl", "UTF-8");
//输出
StringWriter out = new StringWriter();
template.process(classBean,out);
return out.toString();
}
@Override
public String generationController(ClassBean classBean) throws IOException, TemplateException {
Template template = cfg.getTemplate("Controller.ftl", "UTF-8");
//输出
StringWriter out = new StringWriter();
template.process(classBean,out);
return out.toString();
}
}
UI模块(code-generation-ui)
UI模块提供代码生成功能的界面
模块结构
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─lzx
│ │ │ └─code
│ │ │ └─codegenerationui
│ │ │ CodeGenerationUiApplication.java
│ │ │
│ │ └─resources
│ │ │ application.yml
│ │ │
│ │ ├─static
│ │ │ generaCode-ui.html 操作管理界面
│ │ │
│ │ └─templates
界面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
</style>
</head>
<body>
<div id="app">
<!-- 类基本信息 -->
<el-form :inline="true" :model="form" class="demo-form-inline" label-width="150px">
<el-form-item label="类描述">
<el-input v-model="form.classDescribe" placeholder="类描述"></el-input>
</el-form-item>
<el-form-item label="类名">
<el-input v-model="form.className" placeholder="类名"></el-input>
</el-form-item>
<el-form-item label="bean名称">
<el-input v-model="form.springBeanName" placeholder="bean名称"></el-input>
</el-form-item>
<el-form-item label="表名称">
<el-input v-model="form.tableName" placeholder="表名称"></el-input>
</el-form-item>
<el-form-item label="主键在表中的字段名">
<el-input v-model="form.idColumnName" placeholder="主键在表中的字段名"></el-input>
</el-form-item>
<el-form-item label="主键的描述">
<el-input v-model="form.idDescribe" placeholder="主键的描述"></el-input>
</el-form-item>
<el-form-item label="主键字段名">
<el-input v-model="form.idName" placeholder="主键字段名"></el-input>
</el-form-item>
<el-form-item label="主键类型">
<el-input v-model="form.idType" placeholder="主键类型"></el-input>
<template slot-scope="{row,$index}">
<el-select v-model="form.idType" filterable clearable placeholder="请选择">
<el-option
v-for="item in type"
:key="item.name"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</template>
</el-form-item>
</el-form>
<!-- 类基本信息 edn -->
<!-- 操作按钮 -->
<el-form :inline="true" :model="form" class="demo-form-inline" label-width="0px">
<el-form-item>
<el-button type="primary" @click="onAdd">添加字段</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getCode('ENTITY')">生成实体</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getCode('DAO')">生成DAO</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getCode('SERVICE')">生成Service</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getCode('SERVICE_IMPL')">生成Service实现</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getCode('CONTROLLER')">生成Controller</el-button>
</el-form-item>
</el-form>
<!-- 操作按钮 end -->
<!-- 类字段维护 -->
<el-table
:data="form.fields"
style="width: 100%">
<el-table-column
prop="describe"
label="字段描述"
width="180">
<template slot-scope="{row,$index}">
<el-input v-model='row.describe'></el-input>
</template>
</el-table-column>
<el-table-column
prop="name"
label="字段名称">
<template slot-scope="{row,$index}">
<el-input v-model='row.name'></el-input>
</template>
</el-table-column>
<el-table-column
prop="type"
label="字段类型">
<template slot-scope="{row,$index}">
<el-select v-model="row.type" filterable clearable placeholder="请选择">
<el-option
v-for="item in type"
:key="item.name"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
prop="columnName"
label="表的字段名称"
width="180">
<template slot-scope="{row,$index}">
<el-input v-model='row.columnName'></el-input>
</template>
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="150">
<template slot-scope="scope">
<el-button @click="deleteField(scope.$index)" type="danger" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 类字段维护 end-->
<!-- 代码生成结果 -->
<el-dialog title="生成的代码" :visible.sync="dialogTableVisible">
<!-- 生成的代码 -->
<el-form ref="form" :model="form" label-width="0px">
<el-form-item>
<el-input type="textarea" :rows="30" v-model="returnData.data"></el-input>
</el-form-item>
</el-form>
</el-dialog>
<!-- 代码生成结果 end -->
</div>
</body>
<!-- 引入组件库 -->
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el:"#app",
data:{
dialogTableVisible: false,
type:[],
form:{
"classDescribe": "学生表",
"className": "Student",
"idColumnName": "ID",
"idDescribe": "主键",
"idName": "id",
"idType": "String",
"springBeanName": "student",
"tableName": "STUDENT",
"fields": []
},
returnData:{
}
},
mounted(){
this.init();
},
methods:{
/**
* 初始化数据
*/
init(){
//初始化数据
var _this = this;
axios.get(
"http://localhost:30007/codeGeneration/getAllDataType"
).then(function(rsp){
debugger;
_this.type = rsp.data.data;
console.log(this.application);
}).catch(function(error){
debugger;
});
},
/**
* 添加字段
*/
onAdd(){
//添加字段
var _this = this;
_this.form.fields.push({});
},
/**
* 删除字段
*/
deleteField(index){
debugger;
var _this = this;
_this.form.fields.splice(index,1);
},
/**
* 获取生成的代码
* @param code 需要生成的文件代码
*/
getCode(code) {
var _this = this;
axios.post(
"http://localhost:30007/codeGeneration/generationCode/"+code,_this.form
).then(function(rsp){
debugger;
if(rsp){
_this.returnData=rsp.data;
_this.dialogTableVisible = true;
}
}).catch(function (error) {
});
}
}
});
</script>
</html>