一.创建项目
在选择的时候选择下述三个即可,springboot版本选择较低的即可
二.修改配置
修改pom.xml中的依赖项目,便于大家直接cv,下述为所有需要的依赖,可以直接全选之后替换掉初始的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xiaoxin</groupId>
<artifactId>boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>XIAOXINCodeGeneratorDemo</name>
<description>XIAOXINCodeGeneratorDemo</description>
<properties>
<java.version>8</java.version>
<mybatis-plus.vesion>3.5.2</mybatis-plus.vesion>
<sa-token.version>1.33.0</sa-token.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.reini/slf4-cdi -->
<dependency>
<groupId>net.reini</groupId>
<artifactId>slf4-cdi</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<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>
</project>
三.创建mvc所需要的软件包
common,entity,mapper,service,controller,utils
四.创建和配置数据库
1.建表
创建数据库的表的时候每一个字段都需要写上注释
2.修改配置文件application.yml
server:
port: 9099
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2b8
username: root
password: 123456
mvc:
pathmatch:
matching-strategy: ant_path_matcher
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.在template目录中创建controller.java.ftl和entity.java.ftl文件
3.1controller.java.ftl
package ${package.Controller};
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import java.net.URLEncoder;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import ${package.Parent}.common.Result;
import org.springframework.web.multipart.MultipartFile;
import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
@Resource
private ${table.serviceName} ${table.entityPath}Service;
@PostMapping
@SaCheckPermission("${table.entityPath}.add")
public Result save(@RequestBody ${entity} ${table.entityPath}) {
${table.entityPath}Service.save(${table.entityPath});
return Result.success();
}
@PutMapping
@SaCheckPermission("${table.entityPath}.edit")
public Result update(@RequestBody ${entity} ${table.entityPath}) {
${table.entityPath}Service.updateById(${table.entityPath});
return Result.success();
}
@DeleteMapping("/{id}")
@SaCheckPermission("${table.entityPath}.delete")
public Result delete(@PathVariable Integer id) {
${table.entityPath}Service.removeById(id);
return Result.success();
}
@PostMapping("/del/batch")
@SaCheckPermission("${table.entityPath}.deleteBatch")
public Result deleteBatch(@RequestBody List<Integer> ids) {
${table.entityPath}Service.removeByIds(ids);
return Result.success();
}
@GetMapping
@SaCheckPermission("${table.entityPath}.list")
public Result findAll() {
return Result.success(${table.entityPath}Service.list());
}
@GetMapping("/{id}")
@SaCheckPermission("${table.entityPath}.list")
public Result findOne(@PathVariable Integer id) {
return Result.success(${table.entityPath}Service.getById(id));
}
@GetMapping("/page")
@SaCheckPermission("${table.entityPath}.list")
public Result findPage(@RequestParam(defaultValue = "") String name,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<${entity}> queryWrapper = new QueryWrapper<${entity}>().orderByDesc("id");
queryWrapper.like(!"".equals(name), "name", name);
return Result.success(${table.entityPath}Service.page(new Page<>(pageNum, pageSize), queryWrapper));
}
/**
* 导出接口
*/
@GetMapping("/export")
@SaCheckPermission("${table.entityPath}.export")
public void export(HttpServletResponse response) throws Exception {
// 从数据库查询出所有的数据
List<${entity}> list = ${table.entityPath}Service.list();
// 在内存操作,写出到浏览器
ExcelWriter writer = ExcelUtil.getWriter(true);
// 一次性写出list内的对象到excel,使用默认样式,强制输出标题
writer.write(list, true);
// 设置浏览器响应的格式
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
String fileName = URLEncoder.encode("${entity}信息表", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
ServletOutputStream out = response.getOutputStream();
writer.flush(out, true);
out.close();
writer.close();
}
/**
* excel 导入
* @param file
* @throws Exception
*/
@PostMapping("/import")
@SaCheckPermission("${table.entityPath}.import")
public Result imp(MultipartFile file) throws Exception {
InputStream inputStream = file.getInputStream();
ExcelReader reader = ExcelUtil.getReader(inputStream);
// 通过 javabean的方式读取Excel内的对象,但是要求表头必须是英文,跟javabean的属性要对应起来
List<${entity}> list = reader.readAll(${entity}.class);
${table.entityPath}Service.saveBatch(list);
return Result.success();
}
}
</#if>
3.2entity.java.ftl
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
import cn.hutool.core.annotation.Alias;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.partner.boot.common.LDTConfig;
<#if entityLombokModel>
import lombok.Getter;
import lombok.Setter;
<#if chainModel>
import lombok.experimental.Accessors;
</#if>
</#if>
/**
-
- ${table.comment!}
- @author ${author}
- @since KaTeX parse error: Expected 'EOF', got '#' at position 12: {date} */ <#̲if entityLombok…{schemaName}KaTeX parse error: Expected 'EOF', got '#' at position 18: …able.name}") </#̲if> @ApiModel(v…{entity}对象", description = “${table.comment!}”)
<#if superEntityClass??>
public class ${entity} extends KaTeX parse error: Expected 'EOF', got '#' at position 20: …erEntityClass}<#̲if activeRecord…{entity}></#if> {
<#elseif activeRecord>
public class e n t i t y e x t e n d s M o d e l < {entity} extends Model< entityextendsModel<{entity}> {
<#elseif entitySerialVersionUID>
public class ${entity} implements Serializable {
<#else>
public class ${entity} {
</#if>
<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.keyFlag>
<#assign keyPropertyName=“${field.propertyName}”/>
</#if>
<#if field.comment!?length gt 0>
<#if swagger>
// ${field.comment}
@ApiModelProperty("${field.comment}")
@Alias("${field.comment}")
</#if>
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<#elseif field.convert>
@TableId("${field.annotationColumnName}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充设置 ----->
<#if field.convert>
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
@JsonDeserialize(using = LDTConfig.CmzLdtDeSerializer.class)
@JsonSerialize(using = LDTConfig.CmzLdtSerializer.class)
</#if>
<#elseif field.convert>
@TableField("${field.annotationColumnName}")
</#if>
<#-- 乐观锁注解 -->
<#if field.versionField>
@Version
</#if>
<#-- 逻辑删除注解 -->
<#if field.logicDeleteField>
@TableLogic(value = “0”, delval = “id”)
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == “boolean”>
<#assign getprefix=“is”/>
<#else>
<#assign getprefix=“get”/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
<#if chainModel>
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
<#else>
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
</#if>
this.${field.propertyName} = ${field.propertyName};
<#if chainModel>
return this;
</#if>
}
</#list>
</#if>
<#if entityColumnConstant>
<#list table.fields as field>
public static final String ${field.name?upper_case} = "${field.name}";
</#list>
</#if>
<#if activeRecord>
@Override
public Serializable pkVal() {
<#if keyPropertyName??>
return this.${keyPropertyName};
<#else>
return null;
</#if>
}
</#if>
<#if !entityLombokModel>
@Override
public String toString() {
return "${entity}{" +
<#list table.fields as field>
<#if field_index==0>
"${field.propertyName} = " + ${field.propertyName} +
<#else>
", ${field.propertyName} = " + ${field.propertyName} +
</#if>
</#list>
"}";
}
</#if>
}
五.配置代码生成器
1.包装实体类,在common中增加统一结果返回类result.class
package com.xiaoxin.codegeneratordemo.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* xiaoxin
* 接口统一返回包装类
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result implements Serializable {
private static final long serialVersionUID = 42L;
private static final String CODE_SUCCESS = "200";
private static final String CODE_SYS_ERROR = "500";
private String code;
private String msg;
private Object data;
public static Result success() {
return new Result(CODE_SUCCESS, "操作成功", null);
}
public static Result success(Object data) {
return new Result(CODE_SUCCESS, "操作成功", data);
}
public static Result error(String code, String msg) {
return new Result(code, msg, null);
}
public static Result error(String msg) {
return new Result(CODE_SYS_ERROR, msg, null);
}
public static Result error() {
return new Result(CODE_SYS_ERROR, "系统错误", null);
}
}
2.封装数据库连接属性实体类DBprop.class
package com.xiaoxin.datinghubback.utils;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class DBProp {
private String url;
private String username;
private String password;
}
3.封装数据库表列信息工具类TableColumn.class
package com.xiaoxin.datinghubback.utils;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class TableColumn {
private String columnName;
private String dataType;
private String columnComment;
}
4.启动类中加上mapperscan来扫描到mapper包
5.代码生成工具类Generator.class
下述代码中我们一般只需要修改表名,作者名,包名即可
package com.xiaoxin.codegeneratordemo.utils;
import cn.hutool.core.collection.CollUtil;
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.*;
/**
* 代码生成器
* v1.0
* 作者:xiaoxin
*/
@Slf4j
public class CodeGenerator {
private static final String TABLE = "dynamic"; // 表名
private static final String MODULE_NAME = "动态"; // 菜单名称
private static final String PACKAGE_NAME = "com.xiaoxin.datinghubback"; // java代码的包名
private static final String AUTHOR = "xiaoxin"; // 作者
//
// private static final String VUE_CODE_PATH = ""; // 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 SPACE6 = " ";
private static final String SPACE8 = " ";
private static final String SPACE10 = " ";
private static final String SPACE4 = " ";
public static void main(String[] args) throws SQLException {
generateJava(TABLE); // 生成Java后台代码
// generateVue(TABLE); // 生成Vue文件
// generatePermissionSqlData(TABLE); // 生成权限菜单
}
private static void generatePermissionSqlData(String tableName) throws SQLException {
// 获取数据库连接的信息
DBProp dbProp = getDBProp();
// 连接数据库
DataSource dataSource = new SimpleDataSource(dbProp.getUrl(), dbProp.getUsername(), dbProp.getPassword());
Db db = DbUtil.use(dataSource);
String lowerEntity = getLowerEntity(tableName);
// 先删除菜单sql再插入新的sql
db.execute("delete from `sys_permission` where `auth` like '" + lowerEntity + "%' or path like '" + lowerEntity + "%'");
db.execute("INSERT INTO `sys_permission` (`name`, `path`, `icon`, `page`, `type`) " +
"VALUES (?, ?, ?, ?, ? )", MODULE_NAME + "管理", lowerEntity, "grid",
getEntity(tableName), "2");
List<Entity> pages = db.findBy("sys_permission", "path", lowerEntity);
Entity entity = pages.get(0);
Integer pid = entity.getInt("id");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", MODULE_NAME + "查询", lowerEntity + ".list", pid, "3");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", MODULE_NAME + "新增", lowerEntity + ".add", pid, "3");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", MODULE_NAME + "导入", lowerEntity + ".import", pid, "3");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", MODULE_NAME + "导出", lowerEntity + ".export", pid, "3");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", "批量删除", lowerEntity + ".deleteBatch", pid, "3");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", MODULE_NAME + "编辑", lowerEntity + ".edit", pid, "3");
db.execute("INSERT INTO `sys_permission` (`name`, `auth`, `pid`, `type`) " +
"VALUES (?, ?, ?, ?)", MODULE_NAME + "删除", lowerEntity + ".delete", pid, "3");
// 给管理员默认所有的权限
List<Entity> adminRole = db.findBy("sys_role", "flag", "ADMIN");
if (CollUtil.isNotEmpty(adminRole)) {
// 先删除管理员权限
db.execute("delete from `sys_role_permission` where `role_id` = " + adminRole.get(0).getInt("id"));
List<Entity> permissionAll = db.findAll("sys_permission");
// 再添加所有权限给管理员
for (Entity per : permissionAll) {
db.execute("INSERT INTO `sys_role_permission` (`role_id`, `permission_id`) " +
"VALUES (?, ?)", adminRole.get(0).getInt("id"), per.getInt("id"));
}
}
log.debug("========================== 菜单Sql生成完成!!!==========================");
}
private static void generateVue(String tableName) {
List<TableColumn> tableColumns = getTableColumns(tableName);
// 读取模板,生成代码
String vueTemplate = ResourceUtil.readUtf8Str("templates/vue.template");
// 封装模板的代码
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.put("moduleName", MODULE_NAME);
// 生成页面代码
// String vuePage = StrUtil.format(vueTemplate, map); // vuePage是替换字符串模板后的内容
// 写文件
// "D:\\知识星球\\partner-manager\\src\\views\\" 是你vue工程文件的目录
String entity = getEntity(tableName);
// FileUtil.writeUtf8String(vuePage, VUE_CODE_PATH + entity + ".vue");
log.debug("==========================" + entity + ".vue文件生成完成!!!==========================");
}
private static List<TableColumn> getTableColumns(String tableName) {
// 获取数据库连接的信息
DBProp dbProp = getDBProp();
// 连接数据库
DataSource dataSource = new SimpleDataSource("jdbc:mysql://localhost:3306/information_schema", dbProp.getUsername(), dbProp.getPassword());
Db db = DbUtil.use(dataSource);
// 拿到实际要生成代码的数据库的名称
String url = dbProp.getUrl();
String schema = url.substring(url.indexOf("3306/") + 5, url.indexOf("?"));
List<TableColumn> tableColumnList = new ArrayList<>();
try {
List<Entity> columns = db.findAll(Entity.create("COLUMNS").set("TABLE_SCHEMA", schema).set("TABLE_NAME", tableName));
//封装结构化的表数据信息
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);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return tableColumnList;
}
private static String getVueTableBody(List<TableColumn> tableColumnList) {
StringBuilder builder = new StringBuilder();
for (TableColumn tableColumn : tableColumnList) {
if (tableColumn.getColumnName().equalsIgnoreCase("id") && StrUtil.isBlank(tableColumn.getColumnComment())) {
tableColumn.setColumnComment("编号");
}
if (tableColumn.getColumnName().equalsIgnoreCase("deleted") || tableColumn.getColumnName().equalsIgnoreCase("create_time")
|| tableColumn.getColumnName().equalsIgnoreCase("update_time")) { // 排除deleted create_time update_time 这个无需关注的字段
continue;
}
String camelCaseName = StrUtil.toCamelCase(tableColumn.getColumnName());
if (tableColumn.getColumnName().endsWith("img")) {
builder.append(SPACE6).append("<el-table-column label=\"图片\"><template #default=\"scope\"><el-image preview-teleported style=\"width: 100px; height: 100px\" :src=\"scope.row.").append(camelCaseName).append("\" :preview-src-list=\"[scope.row.img]\"></el-image></template></el-table-column>\n");
} else if (tableColumn.getColumnName().endsWith("file")) {
builder.append(SPACE6).append("<el-table-column label=\"文件\"><template #default=\"scope\"> <a :href=\"scope.row.").append(camelCaseName).append("\" target=\"_blank\" style=\"text-decoration: none; color: dodgerblue\">点击下载</a></template></el-table-column>\n");
} else {
builder.append(SPACE6).append("<el-table-column prop=\"").append(camelCaseName).append("\" label=\"").append(tableColumn.getColumnComment()).append("\"></el-table-column>\n");
}
}
return builder.toString();
}
private static String getVueFormBody(List<TableColumn> tableColumnList) {
StringBuilder builder = new StringBuilder();
for (TableColumn tableColumn : tableColumnList) {
if (tableColumn.getColumnName().equalsIgnoreCase("id")) {
continue;
}
if (tableColumn.getColumnName().equalsIgnoreCase("deleted") || tableColumn.getColumnName().equalsIgnoreCase("create_time")
|| tableColumn.getColumnName().equalsIgnoreCase("update_time")) { // 排除deleted create_time update_time 这个无需关注的字段
continue;
}
String camelCaseName = StrUtil.toCamelCase(tableColumn.getColumnName());
builder.append(SPACE8).append("<el-form-item prop=\"").append(camelCaseName).append("\" label=\"").append(tableColumn.getColumnComment()).append("\">\n");
if (tableColumn.getColumnName().contains("time")) {
// 日期时间
builder.append(SPACE10).append("<el-date-picker v-model=\"state.form.").append(camelCaseName)
.append("\" type=\"datetime\" value-format=\"YYYY-MM-DD HH:mm:ss\" placeholder=\"选择日期时间\"></el-date-picker>\n");
} else if (tableColumn.getColumnName().endsWith("date")) {
// 日期
builder.append(SPACE10).append("<el-date-picker v-model=\"state.form.").append(camelCaseName).append("\" type=\"date\" value-format=\"YYYY-MM-DD\" placeholder=\"选择日期\"></el-date-picker>\n");
} else if (tableColumn.getColumnName().endsWith("file")) {
// 文件上传
builder.append(SPACE10).append("<el-upload :show-file-list=\"false\" :action=\"`http://${config.serverUrl}/file/upload`\" ref=\"file\" :headers=\"{ Authorization: token}\" :on-success=\"handleFileUploadSuccess\">\n");
builder.append(SPACE10).append(" <el-button size=\"small\" type=\"primary\">点击上传</el-button>\n");
builder.append(SPACE10).append("</el-upload>\n");
} else if (tableColumn.getColumnName().endsWith("img")) {
// 文件上传
builder.append(SPACE10).append("<el-upload :show-file-list=\"false\" :action=\"`http://${config.serverUrl}/file/upload`\" ref=\"file\" :headers=\"{ Authorization: token}\" :on-success=\"handleImgUploadSuccess\">\n");
builder.append(SPACE10).append(" <el-button size=\"small\" type=\"primary\">点击上传</el-button>\n");
builder.append(SPACE10).append("</el-upload>\n");
} else {
builder.append(SPACE10).append("<el-input v-model=\"state.form.").append(camelCaseName).append("\" autocomplete=\"off\"></el-input>\n");
}
builder.append(SPACE8).append("</el-form-item>\n");
}
return builder.toString();
}
private static String getLowerEntity(String tableName) {
tableName = tableName.replaceAll("t_", "").replaceAll("sys_", "");
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() {
ClassPathResource resource = new ClassPathResource("application.yml");
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(resource);
Properties dbProp = 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()
.logicDeleteColumnName("deleted")
.addTableFills(new Column("create_time", FieldFill.INSERT))
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE));
builder.addInclude(tableName) // 设置需要生成的表名
.addTablePrefix("t_", "sys_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
6.直接运行codegenerator
运行工具类中的代码,控制台中运行成功即可
运行springboot项目,测试接口
找到启动类,直接运行
便于接口测试,在navacat中直接数据生成
随便生成50条数据
随机生成五十条数据
访问localhost:9099/user,访问其中一个接口来测试