集成velocity生成代码,包含controller、service、impl、entity、mapper、vo、xml
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
com.mysql
mysql-connector-j
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
javax.persistence
persistence-api
1.0
org.apache.velocity
velocity-engine-core
2.0
mysql
mysql-connector-java
8.0.26
VelocityCodeGenerator
package com.example.jpacodegenerator;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.util.*;
/**
* Velocity代码生成器
*
* @author JunHao Huang
* @since 2023/6/8 14:33
*/
public class VelocityCodeGenerator {
/**
* 数据库链接工具类
*/
public class JdbcUtils {
/**
* jdbc
*/
private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
/**
* 数据库地址
*/
private static final String DB_URL = "jdbc:mysql://localhost:3306/my_dev?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8";
/**
* 账号
*/
private static final String USER = "root";
/**
* 密码
*/
private static final String PASSWORD = "root";
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName(JDBC_DRIVER);
return DriverManager.getConnection(DB_URL, USER, PASSWORD);
}
}
/**
* 获取表信息工具类
*/
public class TableUtils {
public static ResultSet printTableColumns(Connection conn, String tableName) throws SQLException {
DatabaseMetaData metaData = conn.getMetaData();
return metaData.getColumns(null, null, tableName, null);
}
}
/**
* Velocity工具类,主要获取模板信息
*/
public class VelocityUtil {
private static final String TEMPLATE_PATH = "/templates/";
public static Template getTemplate(String name) {
Properties properties = new Properties();
properties.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
properties.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
VelocityEngine engine = new VelocityEngine(properties);
return engine.getTemplate(TEMPLATE_PATH + name, "UTF-8");
}
}
/**
* 自定义
*/
private static final String BASE_PACKAGE = "cn.com.infox";
private static final String MODULE_NAME = "attendance";
private static final String CLASS_NAME = "MyTest";
private static final String CLASS_NAME_SMART = "myTest";
private static final String AUTHOR = "huangjunhao";
private static final String TABLE_NAME = "myTest";
private static final String MYSQL_TABLE_NAME = "my_test";
/**
* 不需要修改
*/
private static final String CLASS_VO_NAME = CLASS_NAME + "VO";
private static final String CLASS_VO_NAME_SMART = CLASS_NAME_SMART + "VO";
private static final String CLASS_MAPPER_NAME = CLASS_NAME + "Mapper";
private static final String CLASS_CONTROLLER_NAME = CLASS_NAME + "Controller";
private static final String CLASS_SERVICE_NAME = CLASS_NAME + "Service";
private static final String CLASS_SERVICE_IMPL_NAME = CLASS_NAME + "ServiceImpl";
private static final String CONTROLLER_URL = BASE_PACKAGE + "." + MODULE_NAME + ".controller";
private static final String ENTITY_URL = BASE_PACKAGE + "." + MODULE_NAME + ".entity";
private static final String VO_URL = BASE_PACKAGE + "." + MODULE_NAME + ".vo";
private static final String XML_URL = BASE_PACKAGE + "." + MODULE_NAME + ".xml";
private static final String SERVICE_URL = BASE_PACKAGE + "." + MODULE_NAME + ".service";
private static final String SERVICE_IMPL_URL = SERVICE_URL + ".impl";
private static final String MAPPER_URL = BASE_PACKAGE + "." + MODULE_NAME + ".mapper";
/**
* 过滤的字段,实体不生成字段
*/
private static final Map PASS_COLUMS = new HashMap<>();
public static void main(String[] args) throws Exception {
PASS_COLUMS.put("id", "id");
PASS_COLUMS.put("is_deleted", "is_deleted");
PASS_COLUMS.put("create_user", "create_user");
PASS_COLUMS.put("create_time", "create_time");
PASS_COLUMS.put("update_user", "update_user");
PASS_COLUMS.put("update_time", "update_time");
PASS_COLUMS.put("status", "status");
//生成实体
generateEntity(TABLE_NAME + "表的实体类");
//生成VO
generateVO(TABLE_NAME + "表的VO类");
//生成控制器
generateController(TABLE_NAME + "表的Controller层", "我的测试表", "我的测试表接口");
//生成service
generateService(TABLE_NAME + "表的Service层");
//生成service实现类
generateImpl(TABLE_NAME + "表的impl层");
//生成mapper
generateMapper(TABLE_NAME + "表的Mapper");
//生成XML
generateXML();
}
private static void generateXML() {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("className", CLASS_NAME);
context.put("classNameSmart", CLASS_NAME_SMART);
context.put("tableName", MYSQL_TABLE_NAME);
context.put("classVOName", CLASS_VO_NAME);
Template template = VelocityUtil.getTemplate("xml.vm");
// 输出到文件
writeFile(XML_URL, CLASS_MAPPER_NAME, ".xml", template, context);
}
private static void generateVO(String tableDesc) {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("importClasses", Arrays.asList(
ENTITY_URL + "." + CLASS_NAME,
"lombok.EqualsAndHashCode",
"lombok.Data"
));
context.put("tableDesc", tableDesc);
context.put("author", AUTHOR);
context.put("className", CLASS_NAME);
Template template = VelocityUtil.getTemplate("VO.vm");
// 输出到文件
writeFile(VO_URL, CLASS_VO_NAME, ".java", template, context);
}
private static void writeFile(String voUrl, String classVoName, String x, Template template, VelocityContext context) {
try {
String fileUrl = "src/main/java/" + voUrl.replaceAll("\\.", "/");
File dir = new File(fileUrl);
if (!dir.exists()) {
dir.mkdirs();
}
FileWriter writer = new FileWriter(fileUrl + "/" + classVoName + x);
template.merge(context, writer);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void generateEntity(String tableDesc) throws SQLException, ClassNotFoundException {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("importClasses", Arrays.asList(
"cn.com.infox.core.mp.base.BaseEntity",
"io.swagger.annotations.ApiModelProperty",
"lombok.Data",
"lombok.EqualsAndHashCode",
"com.baomidou.mybatisplus.annotation.TableName",
"java.util.Date"
));
context.put("tableDesc", tableDesc);
context.put("author", AUTHOR);
context.put("mysqlTableName", MYSQL_TABLE_NAME);
context.put("className", CLASS_NAME);
Connection conn = JdbcUtils.getConnection();
ResultSet mysqlTable = TableUtils.printTableColumns(conn, MYSQL_TABLE_NAME);
List columnList = new ArrayList<>();
while (mysqlTable.next()) {
Column column2 = new Column();
column2.setRemarks(mysqlTable.getString("REMARKS"));
column2.setJavaType(MysqlDataEnum.getValue(mysqlTable.getString("TYPE_NAME")));
String name = mysqlTable.getString("COLUMN_NAME");
if (PASS_COLUMS.containsKey(name)) {
continue;
}
StringBuffer newName = new StringBuffer();
//包含_的字段将首字母变为大写
if (name.contains("_")) {
String[] split = name.split("_");
for (int i = 0; i < split.length; i++) {
if (i == 0) {
newName.append(split[0]);
} else {
newName.append(split[i].substring(0, 1).toUpperCase() + split[i].substring(1));
}
}
column2.setPropertyName(newName.toString());
} else {
column2.setPropertyName(name);
}
columnList.add(column2);
}
conn.close();
TableInfo tableInfo = new TableInfo();
tableInfo.setColumnList(columnList);
context.put("tableInfo", tableInfo);
Template template = VelocityUtil.getTemplate("entity.vm");
// 输出到文件
writeFile(ENTITY_URL, CLASS_NAME, ".java", template, context);
}
private static void generateMapper(String tableDesc) {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("importClasses", Arrays.asList(
"java.util.List",
VO_URL + "." + CLASS_VO_NAME,
"com.baomidou.mybatisplus.core.mapper.BaseMapper",
"com.baomidou.mybatisplus.core.metadata.IPage",
ENTITY_URL + "." + CLASS_NAME
));
context.put("tableDesc", tableDesc);
context.put("author", AUTHOR);
context.put("className", CLASS_NAME);
context.put("classNameSmart", CLASS_NAME_SMART);
context.put("classVOName", CLASS_VO_NAME);
context.put("classVONameSmart", CLASS_VO_NAME_SMART);
Template template = VelocityUtil.getTemplate("mapper.vm");
// 输出到文件
writeFile(MAPPER_URL, CLASS_MAPPER_NAME, ".java", template, context);
}
private static void generateService(String tableDesc) {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("importClasses", Arrays.asList(
VO_URL + "." + CLASS_VO_NAME,
"cn.com.infox.core.mp.base.BaseService",
"com.baomidou.mybatisplus.core.metadata.IPage",
ENTITY_URL + "." + CLASS_NAME
));
context.put("tableDesc", tableDesc);
context.put("author", AUTHOR);
context.put("className", CLASS_NAME);
context.put("classNameSmart", CLASS_NAME_SMART);
context.put("classVOName", CLASS_VO_NAME);
context.put("classVONameSmart", CLASS_VO_NAME_SMART);
Template template = VelocityUtil.getTemplate("service.vm");
// 输出到文件
writeFile(SERVICE_URL, CLASS_SERVICE_NAME, ".java", template, context);
}
private static void generateImpl(String tableDesc) {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("importClasses", Arrays.asList(
ENTITY_URL + "." + CLASS_NAME,
MAPPER_URL + "." + CLASS_MAPPER_NAME,
SERVICE_URL + "." + CLASS_SERVICE_NAME,
VO_URL + "." + CLASS_VO_NAME,
"cn.com.infox.core.mp.base.BaseServiceImpl",
"com.baomidou.mybatisplus.core.metadata.IPage",
"org.springframework.stereotype.Service"
));
context.put("tableDesc", tableDesc);
context.put("author", AUTHOR);
context.put("className", CLASS_NAME);
context.put("classNameSmart", CLASS_NAME_SMART);
context.put("classVOName", CLASS_VO_NAME);
context.put("classVONameSmart", CLASS_VO_NAME_SMART);
Template template = VelocityUtil.getTemplate("impl.vm");
// 输出到文件
writeFile(SERVICE_IMPL_URL, CLASS_SERVICE_IMPL_NAME, ".java", template, context);
}
private static void generateController(String tableDesc, String apiValue, String apiTag) {
VelocityContext context = new VelocityContext();
context.put("basePackage", BASE_PACKAGE);
context.put("moduleName", MODULE_NAME);
context.put("importClasses", Arrays.asList(
ENTITY_URL + "." + CLASS_NAME,
SERVICE_URL + "." + CLASS_NAME + "Service",
VO_URL + "." + CLASS_VO_NAME,
"cn.com.infox.core.boot.ctrl.BasicController",
"cn.com.infox.core.mp.support.Condition",
"cn.com.infox.core.mp.support.Query",
"cn.com.infox.core.tool.api.R",
"cn.com.infox.core.tool.utils.BeanUtil",
"cn.com.infox.core.tool.utils.Func",
"com.baomidou.mybatisplus.core.metadata.IPage",
"com.baomidou.mybatisplus.extension.plugins.pagination.Page",
"com.github.xiaoymin.knife4j.annotations.ApiOperationSupport",
"io.swagger.annotations.Api",
"io.swagger.annotations.ApiOperation",
"io.swagger.annotations.ApiParam",
"lombok.AllArgsConstructor",
"org.springframework.web.bind.annotation.*",
"javax.validation.Valid",
"java.util.stream.Collectors"
));
context.put("tableDesc", tableDesc);
context.put("author", AUTHOR);
context.put("baseUrl", CLASS_NAME_SMART);
context.put("apiValue", apiValue);
context.put("apiValue", apiTag);
context.put("className", CLASS_NAME);
context.put("classNameSmart", CLASS_NAME_SMART);
context.put("classVOName", CLASS_VO_NAME);
context.put("classVONameSmart", CLASS_VO_NAME_SMART);
Template template = VelocityUtil.getTemplate("controller.vm");
// 输出到文件
writeFile(CONTROLLER_URL, CLASS_CONTROLLER_NAME, ".java", template, context);
}
}
Column
package com.example.jpacodegenerator;
import lombok.Data;
/**
* Mysql字段信息
*
* @author JunHao Huang
* @since 2023/6/8 15:11
*/
@Data
public class Column {
/**
* 字段作用
*/
private String remarks;
/**
* 字段类型
*/
private String javaType;
/**
* 字段名
*/
private String propertyName;
}
MysqlDataEnum
package com.example.jpacodegenerator;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* mysql数据类型转换枚举
*
* @author JunHao Huang
* @since 2023/6/8 17:35
*/
@AllArgsConstructor
@Getter
public enum MysqlDataEnum {
VARCHAR("VARCHAR", "String"),
BIT("BIT", "int"),
DATETIME("DATETIME", "Date"),
INT("INT", "int"),
;
private String key;
private String value;
public static String getValue(String key) {
MysqlDataEnum[] enums = values();
for (MysqlDataEnum approveEnums : enums) {
if (approveEnums.key.equals(key)) {
return approveEnums.value;
}
}
return null;
}
}
TableInfo
package com.example.jpacodegenerator;
import lombok.Data;
import java.util.List;
/**
* @author JunHao Huang
* @since 2023/6/8 15:09
*/
@Data
public class TableInfo {
private List columnList;
}
controller.vm
package ${basePackage}.${moduleName}.controller;
#foreach($importClass in $importClasses)
import ${importClass};
#end
/**
* ${tableDesc}
*
* @author ${author}
*/
@RestController
@AllArgsConstructor
@RequestMapping("/${baseUrl}")
@Api(value = "${apiValue}", tags = "${apiTag}")
public class ${className}Controller extends BasicController {
private ${className}Service ${classNameSmart}Service;
/**
* 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "详情", notes = "传入${classNameSmart}")
public R <${classVOName}> detail(${className} ${classNameSmart}) {
${className} detail = ${classNameSmart}Service.getOne(Condition.getQueryWrapper(${classNameSmart}));
return R.data(detail == null ? null : BeanUtil.copy(detail, ${classVOName}.class));
}
/**
* 分页
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "分页", notes = "传入${classNameSmart}")
public R> list(${className} ${classNameSmart}, Query query) {
IPage<${className}> pages = ${classNameSmart}Service.page(Condition.getPage(query), Condition.getQueryWrapper(${classNameSmart}));
IPage<${classVOName}> page = new Page<>();
BeanUtil.copy(pages, page);
page.setRecords(pages.getRecords().stream().map(p -> BeanUtil.copy(p,${classVOName}.class)).collect(Collectors.toList()));
return R.data(page);
}
/**
* 自定义分页
*/
@GetMapping("/page")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "分页", notes = "传入${classNameSmart}")
public R> page(${classVOName} ${classVONameSmart}, Query query) {
IPage<${classVOName}> pages = ${classNameSmart}Service.select${className}Page(Condition.getPage(query), ${classVONameSmart});
return R.data(pages);
}
/**
* 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 4)
@ApiOperation(value = "新增", notes = "传入${classNameSmart}")
public R save(@Valid @RequestBody ${className} ${classNameSmart}) {
return R.status(${classNameSmart}Service.save(${classNameSmart}));
}
/**
* 修改 打卡规则表
*/
@PostMapping("/update")
@ApiOperationSupport(order = 5)
@ApiOperation(value = "修改", notes = "传入${classNameSmart}")
public R update(@Valid @RequestBody ${className} ${classNameSmart}) {
return R.status(${classNameSmart}Service.updateById(${classNameSmart}));
}
/**
* 新增或修改 打卡规则表
*/
@PostMapping("/submit")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "新增或修改", notes = "传入${classNameSmart}")
public R submit(@Valid @RequestBody ${className} ${classNameSmart}) {
return R.status(${classNameSmart}Service.saveOrUpdate(${classNameSmart}));
}
/**
* 删除 打卡规则表
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 7)
@ApiOperation(value = "逻辑删除", notes = "传入ids")
public R remove(@ApiParam(value = "主键集合", required = true) @RequestBody String ids) {
return R.status(${classNameSmart}Service.deleteLogic(Func.toStrList(ids)));
}
}
entity.vm
package ${basePackage}.${moduleName}.entity;
#foreach($importClass in $importClasses)
import ${importClass};
#end
/**
* ${tableDesc}
*
* @author ${author}
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("${mysqlTableName}")
public class ${className} extends BaseEntity {
#foreach($field in $tableInfo.columnList)
/** $field.remarks */
private ${field.javaType} ${field.propertyName};
#end
}
impl.vm
package ${basePackage}.${moduleName}.service.impl;
#foreach($importClass in $importClasses)
import ${importClass};
#end
/**
* ${tableDesc}
*
* @author ${author}
*/
@Service
public class ${className}ServiceImpl extends BaseServiceImpl<${className}Mapper, ${className}> implements ${className}Service {
@Override
public IPage<${classVOName}> select${className}Page(IPage<${classVOName}> page, ${classVOName} ${classVONameSmart}) {
return page.setRecords(baseMapper.select${classVOName}Page(page, ${classVONameSmart}));
}
}
mapper.vm
package ${basePackage}.${moduleName}.mapper;
#foreach($importClass in $importClasses)
import ${importClass};
#end
/**
* ${tableDesc}
*
* @author ${author}
*/
public interface ${className}Mapper extends BaseMapper<${className}> {
/**
* 自定义分页
*
* @param page 分页条件
* @param ${classVONameSmart} 查询条件
* @return List<${classVOName}>
*/
List<${classVOName}> select${classVOName}Page(IPage page, ${classVOName} ${classVONameSmart});
}
service.vm
package ${basePackage}.${moduleName}.service;
#foreach($importClass in $importClasses)
import ${importClass};
#end
/**
* ${tableDesc}
*
* @author ${author}
*/
public interface ${className}Service extends BaseService<${className}> {
/**
* 自定义分页
*
* @param page 分页数据
* @param ${classVONameSmart} 查询条件
* @return IPage<${classVOName}>
*/
IPage<${classVOName}> select${className}Page(IPage<${classVOName}> page, ${classVOName} ${classVONameSmart});
}
vo.vm
package ${basePackage}.${moduleName}.vo;
#foreach($importClass in $importClasses)
import ${importClass};
#end
/**
* ${tableDesc}
*
* @author ${author}
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ${className}VO extends ${className} {
private static final long serialVersionUID = 1L;
}
xml.vm
请根据公司代码规范生成对应的模板