FreeMarker SpringBoot 代码生成器
这篇大部分代码是用了 https://blog.csdn.net/weixin_43424932/article/details/104253977 这篇文章,只是我用它的代码没跑通,自己修改了一下,然后添加了注释,现在用下面的代码是可以跑通
还有,哪位知道Markdown里FreeMarker模版代码的高亮怎么弄,尴尬,我直接用ftl,没效果,尴尬
FreeMarker教程: http://www.freemarker.net/
maven添加库
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
配置文件 application.yml:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
目录结构:
- java
- resources
- templates
- entity.ftl
- dao.ftl
- mapper.ftl
- controller.ftl
- service.ftl
- serviceImpl.ftl
FreeMarker流程:
- 创建一个Configuration对象,直接new一个对象。构造方法的参数就是FreeMarker对于的版本号。
- 设置模板文件所在的路径。
- 设置模板文件使用的字符集。一般就是utf-8.
- 加载一个模板,创建一个模板对象。
- 创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
- 创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
- 调用模板对象的process方法输出文件。
- 关闭流。
FreeMarkerTools.java:
package com.example.generate.config;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
public class FreeMarkerTools {
@Autowired
JdbcTemplate jdbcTemplate;
private void pathJudgeExist(String path){
File file = new File(path);
if(!file.exists()) {
file.mkdirs();
}
}
public void printFile(Map<String, Object> root, Template template, String filePath, String fileName) throws Exception {
pathJudgeExist(filePath);
File file = new File(filePath, fileName );
if(!file.exists()) {
file.createNewFile();
}
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
template.process(root, out);
out.close();
}
public String capFirst(String str){
return str.substring(0,1).toUpperCase()+str.substring(1).toLowerCase();
}
public String underlineToHump(String para){
StringBuilder result=new StringBuilder();
String a[]=para.split("_");
for(String s:a){
if(result.length()==0){
result.append(s);
}else{
result.append(s.substring(0, 1).toUpperCase());
result.append(s.substring(1).toLowerCase());
}
}
return result.toString();
}
public String getEntityName(String tableName){
return underlineToHump(capFirst(tableName.toLowerCase()));
}
public String getEntityNameLower(String tableName){
return underlineToHump(tableName.toLowerCase());
}
public String convertToJava(String columnType){
String result;
switch (columnType){
case "VARCHAR":{
result = "String";
break;
}
case "INT":{
result = "Integer";
break;
}
case "BIGINT":{
result = "Long";
break;
}
case "FLOAT":{
result = "Float";
break;
}
case "DOUBLE":{
result = "Double";
break;
}
case "DATETIME":{
result = "Date";
break;
}
case "BIT":{
result = "Boolean";
break;
}
default:{
result = "Undefine";
break;
}
}
return result;
}
public String matchResult(String str) {
String regEx2 = "[a-z||A-Z]";
Pattern pattern = Pattern.compile(regEx2);
StringBuilder sb = new StringBuilder();
Matcher m = pattern.matcher(str);
while (m.find()){
for (int i = 0; i <= m.groupCount(); i++)
{
sb.append(m.group());
}
}
return sb.toString();
}
public List<Map<String, String>> getDataInfo(String tableName){
String sql = "show columns from "+tableName;
List<Map<String, Object>> sqlToMap = jdbcTemplate.queryForList(sql);
List<Map<String, String>> columns = new LinkedList<>();
for (Map<String, Object> map : sqlToMap) {
Map<String, String> columnMap = new HashMap<>();
String columnName = map.get("Field").toString();
columnMap.put("columnName", columnName);
String columnType = map.get("Type").toString().toUpperCase();
columnType = matchResult(columnType).trim();
columnType = convertToJava(columnType);
columnMap.put("columnType", columnType);
columnMap.put("entityColumnNo", underlineToHump(columnName));
columns.add(columnMap);
}
return columns;
}
public void generate(Map<String, Object> root,String templateName,String saveUrl,String entityName) throws Exception {
Configuration freeMarker = new Configuration(Configuration.getVersion());
final String TEMPLATE_PATH = ResourceUtils.getURL("classpath:").getPath()+"templates";
freeMarker.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
freeMarker.setDefaultEncoding("utf-8");
Template template = freeMarker.getTemplate(templateName);
printFile(root, template, saveUrl, entityName);
}
}
FreeMarkerController.java:
package com.example.generate.controller;
import com.example.generate.config.FreeMarkerTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class FreeMarkerController {
@Autowired
FreeMarkerTools freeMarkerTools;
@GetMapping("generate")
public String createEntity(String tableName,String saveUrl,String basePackageUrl) throws Exception {
saveUrl = saveUrl == null ? "/Users/zjl/Desktop/xxfilesxx": saveUrl;
basePackageUrl = basePackageUrl == null? "com.example.demo": basePackageUrl;
String entityName = freeMarkerTools.getEntityName(tableName);
Map<String, Object> root = new HashMap<>();
root.put("basePackageUrl", basePackageUrl);
root.put("tableName", tableName);
root.put("entityName", entityName);
root.put("entityNameLower", freeMarkerTools.getEntityNameLower(tableName));
root.put("columns", freeMarkerTools.getDataInfo(tableName));
freeMarkerTools.generate(root,"entity.ftl",saveUrl,entityName+".java");
freeMarkerTools.generate(root,"dao.ftl",saveUrl,entityName+"Dao.java");
freeMarkerTools.generate(root,"mapper.ftl",saveUrl,entityName+"Mapper.xml");
freeMarkerTools.generate(root,"controller.ftl",saveUrl,entityName+"Controller.java");
freeMarkerTools.generate(root,"service.ftl",saveUrl,entityName+"Service.java");
freeMarkerTools.generate(root,"serviceImpl.ftl",saveUrl,entityName+"ServiceImpl.java");
return "生成成功!!!!";
}
}
下面是模版文件:
entity.ftl:
package ${basePackageUrl}.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#if columns??>
<#--循环生成变量-->
<#list columns as col>
/**
* ${col["columnName"]}
*/
private ${col["columnType"]} ${col["entityColumnNo"]};
</#list>
</#if>
}
dao.ftl:
package ${basePackageUrl}.dao;
import ${basePackageUrl}.bean.${entityName};
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ${entityName}Dao {
${entityName} selectByPrimaryKey(Integer id);
}
mapper.ftl:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${basePackageUrl}.dao.${entityName}Dao">
<select id="selectByPrimaryKey" resultType="${basePackageUrl}.bean.${entityName}">
select * from ${tableName} where id=<#noparse>#{id}</#noparse>
</select>
</mapper>
controller.ftl:
package ${basePackageUrl}.controller;
import ${basePackageUrl}.bean.${entityName};
import ${basePackageUrl}.service.${entityName}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class ${entityName}Controller {
@Autowired
${entityName}Service ${entityNameLower}Service;
@GetMapping("/selectByPrimaryKey")
@ResponseBody
public ${entityName} selectByPrimaryKey(Integer id){
return ${entityNameLower}Service.selectByPrimaryKey(id);
}
}
service.ftl:
package ${basePackageUrl}.service;
import ${basePackageUrl}.bean.${entityName};
public interface ${entityName}Service {
${entityName} selectByPrimaryKey(Integer id);
}
serviceImpl.ftl:
package ${basePackageUrl}.service.impl;
import ${basePackageUrl}.bean.${entityName};
import ${basePackageUrl}.dao.${entityName}Dao;
import ${basePackageUrl}.service.${entityName}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ${entityName}ServiceImpl implements ${entityName}Service {
@Autowired
${entityName}Dao ${entityNameLower}Dao;
@Override
public ${entityName} selectByPrimaryKey(Integer id) {
return ${entityNameLower}Dao.selectByPrimaryKey(id);
}
}
打开浏览器: http://localhost:8080/generate?tableName=team
参数是表名
|