使用FreeMarker自动生成代码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l707268743/article/details/83374048

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;
    }
}

5.访问页面,查看效果

http://localhost:8080/freemarker/entity?tableName=users

猜你喜欢

转载自blog.csdn.net/l707268743/article/details/83374048