版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l707268743/article/details/83374048
使用FreeMarker自动生成代码
1. 创建一个SpringBoot项目,或在已有Maven项目上操作
2. pom.xml文件中添加freemarker依赖
<!--freeMarker模板 -->
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
3. 创建freemarker.template.Configuration和对应模板文件ftl
- 3.1 创建
FreeMarkerConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
/**
* @author : liyk
* @version 1.0
* @date : 2018/10/20
*/
@Configuration
public class FreeMarkerConfig {
@Bean
public freemarker.template.Configuration freeMarkerConfiguration() throws IOException {
freemarker.template.Configuration configuration = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_23);
// 设置放置模板的页面路径,此处我在resources目录下新建了文件夹templates,所有模板文件都放在此目录下
ClassPathResource classPathResource = new ClassPathResource("templates");
configuration.setDirectoryForTemplateLoading(classPathResource.getFile());
configuration.setDefaultEncoding("utf-8");
return configuration;
}
}
- 3.2 创建模板文件
entity.ftl
,文件路径需要跟上面的写的路径一致\src\main\resources\templates\
package ${packageUrl};
import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;
/**
* ${tableName}:
*/
@Entity
@Table(name = "${tableName}")
public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
public ${entityName}() {
super();
}
<#if columns??>
<#--循环生成变量-->
<#list columns as col>
/**
* ${col["columnName"]}
*/
private ${col["columnType"]} ${col["entityColumnNo"]};
</#list>
<#--循环生成全体变量的构造方法-->
public ${entityName}(<#list columns as col><#if col_index%3==0>
</#if><#if col_index%3!=0> </#if>${col["columnType"]} ${col["entityColumnNo"]}<#if col_has_next>,</#if></#list>) {
super();
<#list columns as col>
this.${col["entityColumnNo"]} = ${col["entityColumnNo"]};
</#list>
}
<#--生成getter和setter方法-->
<#list columns as col>
<#if (col["columnName"]!"ID") == "ID">@Id
@GeneratedValue(strategy = GenerationType.AUTO)</#if><#if (col["columnType"]!"Date") == "Date">@Temporal(TemporalType.TIMESTAMP)</#if>
@Column(name = "${col["columnNo"]?upper_case}"<#if (col["nullable"]!"NO") == "NO">, nullable = false</#if><#if col["columnLength"] ??>, length = ${col["columnLength"]}</#if>)
public ${col["columnType"]} get${col["entityColumnNo"]?cap_first}() {
return ${col["entityColumnNo"]};
}
public void set${col["entityColumnNo"]?cap_first }(${col["columnType"]} ${col["entityColumnNo"]}) {
this.${col["entityColumnNo"]} = ${col["entityColumnNo"]};
}
</#list>
</#if>
}
4. 创建生成entity要用的Controller
- 4.1 首先创建工具类
CommonUtil.java
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
*
* 这个类功能:
* 1. 用来判断包路径是否存在,若不存在,即创建文件夹;
* 2. 将配好的模板文件写出到指定路径下的文件
* 3. 将配好的模板文件写出到控制台
*/
public class CommonUtil {
/**
* 判断包路径是否存在
* @param path 路径
*/
private static void pathJudgeExist(String path){
File file = new File(path);
if(!file.exists()) {
file.mkdirs();
}
}
//输出到文件
/**
*
* @param root 要在 Templet 中替换的内容
* @param template Templete 实例
* @param filePath 生成文件的路径
* @param fileName 生成文件的名字
* @throws Exception 异常
*/
public static 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();
}
/**
* 输出到控制台
* @param root
* 要在 Templet 中替换的内容
* @param template
* Templete 实例
* @throws TemplateException
* @throws IOException
*/
public static void printConsole(Map<String, Object> root, Template template)
throws TemplateException, IOException {
StringWriter out = new StringWriter();
template.process(root, out);
System.out.println(out.toString());
}
/**
* 首字母大写
* @param str
* @return
*/
public static String cap_first(String str){
return str.substring(0,1).toUpperCase()+str.substring(1).toLowerCase();
}
/***
* 下划线命名转为驼峰命名
*
* @param para
* 下划线命名的字符串
*/
public static 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();
}
/***
* 驼峰命名转为下划线命名
*
* @param para
* 驼峰命名的字符串
*/
public String humpToUnderline(String para){
StringBuilder sb=new StringBuilder(para);
int temp=0;
for(int i=0;i<para.length();i++){
if(Character.isUpperCase(para.charAt(i))){
sb.insert(i+temp, "_");
temp+=1;
}
}
return sb.toString().toUpperCase();
}
/**
* 将[数据库类型]转换成[Java类型],如果遇到没有写的类型,会出现Undefine,在后面补充即可
* @param columnType 数据库类型
* @return Java类型
*/
public static String convert2Java(String columnType){
String result;
switch (columnType){
case "VARCHAR":
case "CHAR":{
result = "String";
break;
}
case "INT":
case "INTEGER":{
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;
}
}
- 4.2 创建controller文件
FreeMarkerController.java
import com.example.freemarkerdemo.util.CommonUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author : liyk
* @version 1.0
* @date : 2018/10/20
*/
@RestController
@RequestMapping("freemarker")
public class FreeMarkerController {
private final Configuration freeMarkerConfiguration;
private final JdbcTemplate jdbcTemplate;
@Autowired
public FreeMarkerController(Configuration freeMarkerConfiguration, JdbcTemplate jdbcTemplate) {
this.freeMarkerConfiguration = freeMarkerConfiguration;
this.jdbcTemplate = jdbcTemplate;
}
@RequestMapping("entity")
public String createEntity(String tableName, String saveUrl) throws Exception {
// 获取模板文件
Template template = freeMarkerConfiguration.getTemplate("entity.ftl");
// 对传入参数进行处理
if (tableName == null) {
return "请先选择数据库表名称";
}
// 此处替换本地要生成entity的路径
saveUrl = saveUrl == null ? "E:\\JAVA\\freemarkerdemo\\src\\main\\java\\com\\example\\freemarkerdemo\\entity" : saveUrl;
tableName = tableName.toLowerCase();
Map<String, Object> root = new HashMap<>();
// 获取表个相关讯息Map
root.put("packageUrl", "com.example.freemarkerdemo.entity");
root.put("tableName", tableName);
String entityName = CommonUtil.underlineToHump(CommonUtil.cap_first(tableName));
root.put("entityName", entityName);
root.put("columns", getDataInfo(tableName));
CommonUtil.printFile(root, template, saveUrl, entityName + ".java");
return "entity生成成功";
}
private List<Map<String, String>> getDataInfo(String tableName){
// mysql查询表结构的语句,如果是其他数据库,修改此处查询语句
String sql = "SELECT distinct COLUMN_NAME,DATA_TYPE,column_comment,IS_NULLABLE,CHARACTER_MAXIMUM_LENGTH " +
"from INFORMATION_SCHEMA.Columns " +
"where table_name=? ";
List<Map<String, Object>> sqlToMap = jdbcTemplate.queryForList(sql, tableName);
List<Map<String, String>> columns = new LinkedList<>();
for (Map map : sqlToMap) {
Map<String, String> columnMap = new HashMap<>(16);
// 字段代号
String columnNo = map.get("COLUMN_NAME").toString().toLowerCase();
columnMap.put("columnNo", columnNo);
// 字段名称
String columnName = map.get("column_comment").toString();
columnName = "ID".equalsIgnoreCase(columnNo) ? "ID" : columnName;
columnMap.put("columnName", columnName);
// 字段类型
String columnType = map.get("DATA_TYPE").toString().toUpperCase();
columnType = CommonUtil.convert2Java(columnType);
columnMap.put("columnType", columnType);
// 字段代号对应的实体类代号
columnMap.put("entityColumnNo", CommonUtil.underlineToHump(columnNo));
// 字段非空否
String nullable = map.get("IS_NULLABLE").toString();
columnMap.put("nullable", nullable);
// 判断字符串最大长度
Object columnLengthObj = map.get("CHARACTER_MAXIMUM_LENGTH");
if (columnLengthObj != null) {
String columnLength = columnLengthObj.toString();
columnMap.put("columnLength", columnLength);
}
columns.add(columnMap);
}
return columns;
}
}