案例--使用freemarker实现代码自动生成

freemarker是一款模板引擎,一种基于模板和数据,并用来生成输出文本(HTML、配置文件,源代码等)的工具。

freemarker模板文件相关语法

1、输出基本数据类型或对象属性
${数据} 或者 ${对象.属性}
如:
    ${name}
    ${user.username}


2.输出集合
<#list userList as item>
    ${item.username}
</#list>

3.if判断
#list userList as item>
    <#if item.username == 'U1'>
        ${item.username},
    <#elseif item.username == 'U2'>
        你好  ${item.username},
    <#else >
        hello  ${item.username} 。
    </#if>
</#list>
----------------------------------
<#list userList as item>
    <#if item_has_next>
        ${item.username},
    <#else >
        ${item.username}
    </#if>
</#list>

4.当存在 '#{' 要保留时如需要转义

 ${r"#{"}

测试实例:

新建maven项目,pom添加freemarker的依赖

    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.23</version>
    </dependency>

模板文件hello.ftl

<html>
<HEAD>
    <meta charset="UTF-8">
</HEAD>
<BODY>
hello ${name}
<br />
你好 ${user.username}
<br />
<#list userList as item>
    ${item.username}
</#list>
<br />
<#list userList as item>
    <#if item.username == 'U1'>
        ${item.username},
    <#elseif item.username == 'U2'>
        你好  ${item.username},
    <#else >
        hello  ${item.username} 。
    </#if>
</#list>
<br />
<#list userList as item>
    <#if item_has_next>
        ${item.username},
    <#else >
        ${item.username}
    </#if>
</#list>

</BODY>
</html>

User类:

package cn.code;

public class User {

    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

测试类:

package cn.code.test;

import cn.code.User;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

    public static void main(String[] args) throws Exception {

        //创建configuration对象
        Configuration configuration = new Configuration(Configuration.getVersion());

        //设置模板所在路径
        String path = "E:\\IdeaProjects\\generator-demo\\src\\main\\resources\\";
        configuration.setDirectoryForTemplateLoading(new File(path));

        //获取模板对应实例,hello.ftl为模板路径下的模板文件
        Template template = configuration.getTemplate("hello.ftl");

        //指定生成文件的保存路径
        String savePath = "E:\\IdeaProjects\\generator-demo\\src\\main\\java\\cn\\code\\test\\hello.html";
        FileOutputStream stream = new FileOutputStream(savePath);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(stream);

        //组装数据
        Map param = new HashMap();
        User user = new User();
        user.setUsername("Lily");
        param.put("name","Tom");
        //输出对象
        param.put("user",user);
        //输出集合
        List<User> userList = new ArrayList<>();
        User user1 = new User();
        user1.setUsername("U1");
        User user2 = new User();
        user2.setUsername("U2");
        User user3 = new User();
        user3.setUsername("U3");

        userList.add(user1);
        userList.add(user2);
        userList.add(user3);

        param.put("userList",userList);

        //传参,生成数据文件
        template.process(param, outputStreamWriter);

    }
}

 

<html>
<HEAD>
    <meta charset="UTF-8">
</HEAD>
<BODY>
hello Tom
<br />
你好 Lily
<br />
    U1
    U2
    U3
<br />
        U1,
        你好  U2,
        hello  U3 。
<br />
        U1,
        U2,
        U3

</BODY>
</html>

生成pojo案例:

1、新建maven项目,pom添加freemarker与mysql连接的依赖,注意版本号要与自己安装的mysql版本一致

    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.23</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.15</version>
    </dependency>
 

新增pojo模板文件

package cn.code.beans;

import java.io.Serializable;


public class ${table.className} implements Serializable {

    <#list table.columns as column>
         //${column.remarks}
         private ${column.javaType} ${column.fieldName};
    </#list>

    <#list table.columns as column>
    public void set${column.upperFieldName} (${column.javaType}  ${column.fieldName} ){
        this.${column.fieldName}=${column.fieldName};
    }

    public  ${column.javaType} get${column.upperFieldName}(){
        return this.${column.fieldName};
    }
    </#list>
}

新增数据库表名与列名的描述

package cn.code.module;

import java.util.ArrayList;
import java.util.List;

public class Table {

    //数据库表名
    private String tableName;

    //表名对应的类名
    private String className;

    //表中的列,一对多
    List<Column> columns = new ArrayList<>();

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public List<Column> getColumns() {
        return columns;
    }

    public void setColumns(List<Column> columns) {
        this.columns = columns;
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
package cn.code.module;

public class Column {

    //列名
    private String columnName;

    //列名对应的属性名
    private String fieldName;

    //首字母大写的属性名
    private String upperFieldName;

    //列类型,数据库类型
    private String columnType;

    //列类型对应的java类型
    private String javaType;

    //备注
    private String remarks;

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }

    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getUpperFieldName() {
        return upperFieldName;
    }

    public void setUpperFieldName(String upperFieldName) {
        this.upperFieldName = upperFieldName;
    }

    public String getColumnType() {
        return columnType;
    }

    public void setColumnType(String columnType) {
        this.columnType = columnType;
    }

    public String getJavaType() {
        return javaType;
    }

    public void setJavaType(String javaType) {
        this.javaType = javaType;
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

数据库相关配置文件database.properties,

注意mysql 8x以上,driver的值,url后面添加 &serverTimezone=GMT ,不然会报异常

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
user=root
password=root

 

相关工具类PropertiesUtils.java 

package cn.code.util;

import java.io.InputStreamReader;
import java.util.Properties;


public class PropertiesUtils {

    private static Properties props;

    /**
     * 加载配置文件
     *
     * @param fileName
     */
    private static void readProperties(String fileName) {
        try {
            props = new Properties();
            InputStreamReader inputStream = new InputStreamReader(PropertiesUtils.class.getClassLoader().getResourceAsStream(fileName), "UTF-8");
            props.load(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 根据key读取对应的value
     *
     * @param key
     * @return
     */
    public static String get(String fileName,String key) {
        readProperties(fileName);
        //System.out.println(props.getProperty(key));
        return props.getProperty(key);
    }

}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
package cn.code.util;

public class StringUtils {

    //根据数据库列类型返回相应的java类型
    public static String switchType(String columnName) {
        String javaType = null;

        switch (columnName) {

            case "VARCHAR":
                javaType = "String";
                break;
            case "INT":
                javaType = "Integer";
                break;
            case "DATETIME":
                javaType = "Date";
                break;
            default:
                javaType = "String";

        }

        return javaType;
    }

    /**
     * 字符串首字母大写
     *
     * @param str
     * @return
     */
    public static String captureName(String str) {

        return String.valueOf(str.charAt(0)).toUpperCase() + str.substring(1);
    }

    /**
     * 去除下划线,下划线后的首字母大写
     *
     * @param str
     * @return
     */
    public static String putOffUnderline(String str) {

        int idx = str.indexOf("_");
        if (idx == -1) return str;

        String s1 = str.replaceFirst("_", "");
        String s2 = s1.substring(0, idx) + String.valueOf(s1.charAt(idx)).toUpperCase() + s1.substring(idx + 1);

       /* String[] strings = str.split("_");

        for (int i = 0; i < strings.length; i++) {
            if (i == 0)
                ret += strings[i];
            else
                ret += String.valueOf(strings[i].charAt(0)).toUpperCase() + strings[i].substring(1);
        }*/

        return putOffUnderline(s2);
    }

    public static void main(String[] args) {
        System.out.println(putOffUnderline("tb_test_a"));
    }


}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

数据库连接与获取表名,与表名对应的列名TableUtils 

package cn.code.util;

import cn.code.module.Column;
import cn.code.module.Table;
import cn.code.util.PropertiesUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class TableUtils {

    private static String DBDRIVER = PropertiesUtils.get("database.properties", "driver");

    private static String DBURL = PropertiesUtils.get("database.properties", "url");

    private static String DBUSER = PropertiesUtils.get("database.properties", "user");

    private static String DBPASS = PropertiesUtils.get("database.properties", "password");

    private static Connection connection;

    private static DatabaseMetaData dbmd;

    static {

        try {
            //连接数据库
            Class.forName(DBDRIVER);
            connection = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
            //获取metaData
            dbmd = connection.getMetaData();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static List<Table> getTable() {

        List<Table> tableList = new ArrayList<>();
        //获取数据库连接
        try {
            //获取所有表名的结果集
            ResultSet rs = dbmd.getTables(null, null, null, new String[]{"TABLE"});
            //遍历结果集
            while (rs.next()) {
                Table table = new Table();//tb_test_a -> TbTestA
                String tableName = rs.getString("TABLE_NAME");
                table.setTableName(tableName);
                table.setClassName(StringUtils.captureName(StringUtils.putOffUnderline(tableName)));
                table.setColumns(getColumns(tableName));
                tableList.add(table);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableList;
    }

    public static List<Column> getColumns(String tableName) {

        List<Column> columnList = new ArrayList<>();

        try {
            ResultSet rs = dbmd.getColumns(null, "%", tableName, "%");
            while (rs.next()) {
                Column column = new Column();
                String columnName = rs.getString("COLUMN_NAME");
                String columnType = rs.getString("TYPE_NAME");
                String remarks = rs.getString("REMARKS");

                column.setColumnName(columnName);
                column.setColumnType(columnType);
                column.setRemarks(remarks);
                column.setFieldName(columnName);
                column.setUpperFieldName(StringUtils.captureName(columnName));
                column.setJavaType(StringUtils.switchType(columnType));

                columnList.add(column);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return columnList;

    }

    public static void main(String[] args) {
        //getTable();
        //getColumns("tb_test_b");

        //测试
        List<Table> tableList = getTable();
        for (Table table: tableList) {
            System.out.println(table.getTableName());
        }


    }
}

freemarker环境初始化

package cn.code;

import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Generator {

    private Configuration configuration;

    //完成环境初始化
    public void init(String path) throws Exception {

        configuration = new Configuration(freemarker.template.Configuration.getVersion());

        //设置模板所在路径
        configuration.setDirectoryForTemplateLoading(new File(path));

    }

    public void process(String tempName, String savePath, Map<String, Object> param) throws Exception {

       

        //获取模板对应实例
        Template template = configuration.getTemplate(tempName);
        //初始化保存路径
        FileOutputStream stream = new FileOutputStream(savePath);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(stream);
        //传参,生成数据
        template.process(param, outputStreamWriter);

    }

   
}

传送从数据库读取的数据并生成pojo

package cn.code.ssm;

import cn.code.Generator;
import cn.code.module.Table;
import cn.code.util.TableUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ModuleHandler {

    private Generator generator = new Generator();

    private String templatePath = this.getClass().getClassLoader().getResource("").getPath()+"\\module\\";

    private String savePath = "E:\\IdeaProjects\\generator-demo\\src\\main\\java\\cn\\code\\beans";

    public void exectue() throws Exception {

        //获取table对应的实例
        List<Table> tableList = TableUtils.getTable();
        Map<String,Object> param = new HashMap<>();

        for (Table table:tableList){
            param.put("table",table);
            generator.init(templatePath);
            generator.process("module.ftl",savePath+"\\"+table.getClassName()+".java",param);
        }
    }

    public static void main(String[] args) throws Exception {
        ModuleHandler moduleHandler = new ModuleHandler();
        moduleHandler.exectue();
    }
}

生成的pojo

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值