VUE代码生成器
创建项目
1 创建项目,删除不需要文件
2 修改 spring 版本
3.application.properties 改名为 application.yml,并配置文件
server:
port: 9090
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/partner?serverTimezone=GMT%2b8
username: root
password: root
# swagger
mvc:
pathmatch:
matching-strategy: ant_path_matcher
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4.配置阿里云,引入依赖
<properties>
<mybatis-plus.vesion>3.5.2</mybatis-plus.vesion>
</properties>
<dependencies>
<!-- hutool工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.10</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter-test</artifactId>
<version>${mybatis-plus.vesion}</version>
</dependency>
<!-- 代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus.vesion}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<!-- 配置阿里云 -->
<repositories>
<repository>
<id>nexus-aliyun</id>
<name>nexus-aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
5.在resources文件夹下建立mapper文件夹,删除resources文件夹下static文件夹
6.导入以前已经写过的文件,新建一些文件夹controller、service、mapper、entity,修改配置。
还有全局异常处理
7.引入代码生成器
注意配置@MapperScan()
生成结果:
后端代码生成器
package com.example.codegeneratordemo.utils;
import cn.hutool.db.Db;
import cn.hutool.db.DbUtil;
import cn.hutool.db.ds.simple.SimpleDataSource;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import javax.sql.DataSource;
import java.util.Properties;
import java.util.Collections;
public class CodeGenerator {
private static final String TABLE = "sys_user";
private static final String PACKAGE_NAME = "com.example.codegeneratordemo";
private static final String AUTHOR = "小熊";
private static final String PROJECT_PATH = System.getProperty("user.dir");
public static final String MAPPER_XML_PATH = "/src/main/resources/mapper/";
public static final String JAVA_CODE_PATH = "/src/main/java/";
public static void main(String[] args) {
generateJava(TABLE);
}
private static DBProp getDBProp() {
// 从 application.yml 取数据库连接信息
ClassPathResource resource = new ClassPathResource("application.yml");
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(resource);
Properties dbProp = yamlPropertiesFactoryBean.getObject();
// return yamlPropertiesFactoryBean.getObject();
return DBProp.builder().url(dbProp.getProperty("spring.datasource.url")) // 字符串属性 不是对象属性
.username(dbProp.getProperty("spring.datasource.username"))
.password(dbProp.getProperty("spring.datasource.password")).build();
}
private static void generateJava (String tableName){
DBProp dbProp = getDBProp();
FastAutoGenerator.create(dbProp.getUrl(), dbProp.getUsername(), dbProp.getPassword())
.globalConfig(builder -> {
builder.author(AUTHOR)//设置作者
.enableSwagger()
.disableOpenDir()
.outputDir(PROJECT_PATH + JAVA_CODE_PATH);//指定输出目录
})
.packageConfig(builder -> {
builder.parent(PACKAGE_NAME) // 设置父包名
.moduleName("") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, PROJECT_PATH + MAPPER_XML_PATH)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.controllerBuilder().fileOverride().enableRestStyle().enableHyphenStyle()
.serviceBuilder().fileOverride()
.mapperBuilder().fileOverride()
.entityBuilder().fileOverride().enableLombok()
.addTableFills(new Column("create_time", FieldFill.INSERT));
builder.addInclude(tableName) // 设置需要生成的表名
.addTablePrefix("t_", "sys_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
前端代码生成器
hutool工具类 DbUtil: https://hutool.cn/docs/#/db/%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%80%E5%8D%95%E6%93%8D%E4%BD%9C-Db
拿到指定数据库的表、字段、字段类型、注释等。查出来后封装一个对象,从对象里取出所有信息。
SELECT * FROM `COLUMNS` WHERE TABLE_SCHEMA = 'partner' AND TABLE_NAME = 'sys_user'
1.获取数据库连接属性,封装 DBProp.java ,将属性写在类里。
package com.partner.boot.utils;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class DBProp {
private String url;
private String username;
private String password;
}
private static DBProp getDBProp() {
// 从 application.yml 取数据库连接信息
ClassPathResource resource = new ClassPathResource("application.yml");
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(resource);
Properties dbProp = yamlPropertiesFactoryBean.getObject();
// return yamlPropertiesFactoryBean.getObject();
// 字符串属性 不是对象属性
return DBProp.builder().url(dbProp.getProperty("spring.datasource.url"))
.username(dbProp.getProperty("spring.datasource.username"))
.password(dbProp.getProperty("spring.datasource.password")).build();
}
2.连接使用数据库
3 封装 TableColumn 类,封装结构化的表数据信息。
package com.example.codegeneratordemo.utils;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class TableColumn {
private String columnName;
private String dataType;
private String columnComment;
}
4 创建 vue.template ,src/main/resources/templates/vue.template。
5 读取模板,生成代码
单生成的代码和模一样,接下来要做的就是根据不同数据表生成相应文件
6 修改 vue.template 代码,使其动态生成模板 。
{lowerEntity}六处、{tableBody} 一处、{formBody}一处
7、处理获取 {lowerEntity}、{tableBody} 、{formBody}
getVueTableBody() getVueFormBody()
完整代码
package com.example.codegeneratordemo.utils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.DbUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.simple.SimpleDataSource;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
@Slf4j
public class CodeGenerator {
private static final String TABLE = "dynamic";
private static final String PACKAGE_NAME = "com.example.codegeneratordemo";
private static final String AUTHOR = "小熊";
private static final String VUE_CODE_PATH = "C:\\Users\\Administrator.DESKTOP-B173SQA\\Desktop\\codeGenerator-vue\\";
// 不需要改
private static final String PROJECT_PATH = System.getProperty("user.dir");
public static final String MAPPER_XML_PATH = "/src/main/resources/mapper/";
public static final String JAVA_CODE_PATH = "/src/main/java/";
// 格式化代码
private static final String SPACE8 = " ";
public static void main(String[] args) {
// generateJava(TABLE);
generateVue(TABLE);
}
private static void generateVue (String tableName) {
List<TableColumn> tableColumns = getTableColumns(tableName);
// 4 读取模板,生成代码
// String vueTemplate = ResourceUtil.readStr("templates/vue.template", StandardCharsets.UTF_8);
String vueTemplate = ResourceUtil.readUtf8Str("templates/vue.template");
// System.out.println(vueTemplate);
// 封装模板的代码
// 把 map 作为一个模板 替换符
Map<String, String> map = new HashMap<>();
map.put("lowerEntity", getLowerEntity(tableName)); // 接口前缀
String vueTableBody = getVueTableBody(tableColumns);
map.put("tableBody", vueTableBody);
String vueFormBody = getVueFormBody(tableColumns);
map.put("formBody", vueFormBody);
// 生成页面代码
// 把 map 中数据 传到 vueTemplate 中
// vuePage是替换字符串模板后的内容
String vuePage = StrUtil.format(vueTemplate, map);
// // 写文件
// // "D:\\IdeaProjects\\partner-manager\s\rc\\views" 是你vue工程文件的目录
// FileUtil.writeUtf8String(vuePage, "C:\\Users\\Administrator.DESKTOP-B173SQA\\Desktop\\codeGenerator-vue\\"+ tableName + ".vue");
// System.out.println("vue文件生成完成!!!");
String entity = getEntity(tableName);
FileUtil.writeUtf8String(vuePage, VUE_CODE_PATH + entity + ".vue");
log.debug("==========================" + entity + ".vue文件生成完成!!!==========================");
}
private static List<TableColumn> getTableColumns(String tableName) {
// 1.获取数据库连接的信息
DBProp dbProp = getDBProp();
// 2.连接数据库
DataSource dataSource = new SimpleDataSource( "jdbc:mysql://localhost:3306/information_schema" , dbProp.getUsername(), dbProp.getPassword());
Db db = DbUtil.use(dataSource);
// 3.操作数据库
// 拿到实际要生成代码的数据库的名称
// jdbc:mysql://localhost:3306/partner?serverTimezone=GMT%2b8
// url.indexOf("3306/") 到的是第一个位置所以要+5
String url = dbProp.getUrl();
String schema = url.substring(url.indexOf("3306/") + 5, url.indexOf("?"));
// partner 可以不写死 因为后端没有传入partner,从.yml中的spring.datasource.url 中截取 得到 schema
// columns 存储的是表字段集合
List<TableColumn> tableColumnList = new ArrayList<>();
try {
List<Entity> columns = db.findAll(Entity.create("COLUMNS").set("TABLE_SCHEMA", schema).set("TABLE_NAME", tableName));
// columns.forEach(System.out::println);
// 封装结构化的表数据信息
for (Entity entity : columns) {
String columnName = entity.getStr("COLUMN_NAME"); // 字段名称
String dataType = entity.getStr("DATA_TYPE"); // 数据类型
String columnComment = entity.getStr("COLUMN_COMMENT"); // 数据注释
TableColumn tableColumn = TableColumn.builder().columnName(columnName).dataType(dataType).columnComment(columnComment).build();
tableColumnList.add(tableColumn);
}
// System.out.println(tableColumnList);
}catch (SQLException e){
throw new RuntimeException(e);
}
return tableColumnList;
}
private static String getVueTableBody(List<TableColumn> tableColumnList) {
StringBuilder builder = new StringBuilder();
for (TableColumn tableColumn : tableColumnList) {
// id 有时候没写注释 需要特殊处理
if (tableColumn.getColumnName().equalsIgnoreCase("id") && StrUtil.isBlank(tableColumn.getColumnComment())) {
tableColumn.setColumnComment("编号");
}
// 排除 deleted create_time update_time 这个无需关注的字段
if (tableColumn.getColumnName().equalsIgnoreCase("deleted") || tableColumn.getColumnName().equalsIgnoreCase("create_time")
|| tableColumn.getColumnName().equalsIgnoreCase("update_time")) {
continue;
}
// 动态生成 注意添加换行
String column = SPACE8 + "<el-table-column prop=\"" + tableColumn.getColumnName() + "\" label=\""
+ tableColumn.getColumnComment() + "\"></el-table-column>\n";
// 连接所有字符串
builder.append(column);
}
return builder.toString();
}
private static String getVueFormBody(List<TableColumn> tableColumnList) {
StringBuilder builder = new StringBuilder();
for (TableColumn tableColumn : tableColumnList) {
// 表单里没有id选项
if (tableColumn.getColumnName().equalsIgnoreCase("id")) {
continue;
}
// 排除deleted create_time update_time 这个无需关注的字段
if (tableColumn.getColumnName().equalsIgnoreCase("deleted") || tableColumn.getColumnName().equalsIgnoreCase("create_time")
|| tableColumn.getColumnName().equalsIgnoreCase("update_time")) {
continue;
}
// 动态生成 注意添加换行
String column = SPACE8 + "<el-form-item prop=\"" + tableColumn.getColumnName() + "\" label=\"" + tableColumn.getColumnComment() + "\" >\n" +
SPACE8 + " <el-input v-model=\"state.form." + tableColumn.getColumnName() + "\" autocomplete=\"off\" />\n" +
SPACE8 + "</el-form-item>\n";
// 连接所有字符串
builder.append(column);
}
return builder.toString();
}
private static String getLowerEntity(String tableName) {
tableName = tableName.replaceAll("t_", "").replaceAll("sys_", "");
// toCamelCase 方法 :sys_user -> user; user_rel -> userRel 把下划线转驼峰
return StrUtil.toCamelCase(tableName);
}
private static String getEntity(String tableName) {
String lowerEntity = getLowerEntity(tableName);
// 把第一个字母变大写
return lowerEntity.substring(0, 1).toUpperCase() + lowerEntity.substring(1);
}
private static DBProp getDBProp() {
// 从 application.yml 取数据库连接信息
ClassPathResource resource = new ClassPathResource("application.yml");
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(resource);
Properties dbProp = yamlPropertiesFactoryBean.getObject();
// return yamlPropertiesFactoryBean.getObject();
return DBProp.builder().url(dbProp.getProperty("spring.datasource.url")) // 字符串属性 不是对象属性
.username(dbProp.getProperty("spring.datasource.username"))
.password(dbProp.getProperty("spring.datasource.password")).build();
}
private static void generateJava (String tableName){
DBProp dbProp = getDBProp();
FastAutoGenerator.create(dbProp.getUrl(), dbProp.getUsername(), dbProp.getPassword())
.globalConfig(builder -> {
builder.author(AUTHOR)//设置作者
.enableSwagger()
.disableOpenDir()
.outputDir(PROJECT_PATH + JAVA_CODE_PATH);//指定输出目录
})
.packageConfig(builder -> {
builder.parent(PACKAGE_NAME) // 设置父包名
.moduleName("") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, PROJECT_PATH + MAPPER_XML_PATH)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.controllerBuilder().fileOverride().enableRestStyle().enableHyphenStyle()
.serviceBuilder().fileOverride()
.mapperBuilder().fileOverride()
.entityBuilder().fileOverride().enableLombok()
.addTableFills(new Column("create_time", FieldFill.INSERT));
builder.addInclude(tableName) // 设置需要生成的表名
.addTablePrefix("t_", "sys_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}