使用Freemarker模板生成JAVA代码

前言

记一次Freemarker的套路过程,通过JDBC访问数据库,查询表结构,对应生成Dao、Service、Entity、ServiceImpl等java文件,主要是为了实现之前一篇博文的注解整合SSM项目代码的生成功能。

传入freemarker的数据格式为:Map<String, Map<String, Object>>
也可以用其他的,个人感觉这个方便一点。

具体套路如下:
1. 涉及的JAR
freemarker-2.3.19.jar(各版本均可)
mysql-connector-java-5.1.13-bin.jar

  1. 代码实现

2.1 使用JDBC方式连接数据库,组装好数据并且存入map

    public static Map<String, Map<String, Params>> connect(String driver,
            String url, String username, String password) {
    try {
        //加载驱动类
        Class.forName(driver);
    }catch (ClassNotFoundException e1) {
        e1.printStackTrace();
    }
    //将各种流放入try()中,将由try来执行close()操作
    try (Connection con 
            = DriverManager.getConnection(url, username,password);
        PreparedStatement ps 
            = con.prepareStatement(
                "select table_name,column_name,column_comment,
                column_type,column_key,column_default 
                from INFORMATION_SCHEMA.Columns 
                where table_name='m_user' 
                and table_schema='test'");
                ResultSet rs = ps.executeQuery();
    ) {

            Map<String, Map<String, Params>> map = new HashMap<>();
            Map<String, Params> mapCommon = new HashMap<>();
                        int i = 0;
            while (rs.next()) {
                String tableName = rs.getString("table_name");
                String className = tableName.replaceAll("m_", "");
                String columnName = rs.getString("column_name");
                String type = rs.getString("column_type");
                if("(varchar(255)".equals(type)){
                    type = "String";
                }else if("int(11)".equals(type)){
                    type = "int";
                }
                // 使首字母大写
                String classNameUpCase = FreemarkUtil.toUpString(className);
                String columnNameUpCase = FreemarkUtil.toUpString(columnName);
                //这里只是使用一个实体类接收ResultSet的结果
                Params p = new Params.Build()
                        .column(columnName)
                        .comment(rs.getString("column_comment"))
                        .defaultName(rs.getString("column_default"))
                        .type(type)
                        .key(rs.getString("column_key")).tableName(tableName)
                        .className(className).classNameUpCase(classNameUpCase)
                        .columnNameUpCase(columnNameUpCase)
                        .buildParams();
                //将每一个组装好的实体类存入MAP,指定key
                mapCommon.put("Params" + i, p);
                i++;
            }
            //全部的MAP
            map.put("Paramss", mapCommon);
            System.out.println(map);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
}

2.2 Freemarker的使用

2.2.1 代码的调用

public class FreemarkUtil {
    private static String driver = "com.mysql.jdbc.Driver";
    private static String url = "jdbc:mysql://localhost:3306/test";
    private static String username = "root";
    private static String password = "*******";
    //你模板放置的路径
    private static String basePath = "D:\\Workspaces\\MyEclipse for Spring 2014\\genateJavaCode\\src\\genateJavaCode";
    // 创建Configuration实例
    private static Configuration cfg = new Configuration();

    public static void genateCode() {
        Template temp = null;
        File loadTemplateFile = new File(basePath);
        try {
            cfg.setDirectoryForTemplateLoading(loadTemplateFile);
            String saveDir = basePath + "/test";

            Map<String, Map<String, Params>> classPropties = ConnectMySql
                    .connect(driver, url, username, password);
            SetJavaCode(temp, saveDir, classPropties);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 首字母大写
    public static String toUpString(String className) {
        char[] cs = className.toCharArray();
        cs[0] -= 32;
        String ClassName = String.valueOf(cs);
        return ClassName;
    }

    public static void SetJavaCode(Template temp, String saveDir,
            Map<String, Map<String, Params>> classPropties) {

        Map<String, Params> m = classPropties.get("Paramss");
        //每一个实例里面都存有tableName,这里取第0个拿tableName
        String tableName = (String) (m.get("Params0").getTableName());
        //表明为m_user,指定类名为User
        String className = tableName.replaceAll("m_", "");
        // 使首字母大写
        String ClassName = toUpString(className);
        // 存入,作为参数给页面 className:作为引用名 ClassName:作为类名
        String fileNameEntityPath = saveDir 
            + "/entity/" + ClassName + ".java";
        String fileNameDaoPath = saveDir  
            + "/dao/" + ClassName + "Dao.java";
        String fileNameServicePath = saveDir 
            + "/service/" + ClassName+ "Service.java";
        String fileNameServiceImplPath = saveDir 
            + "/service/impl/" + ClassName + "ServiceImpl.java";
        File newsDir = new File(saveDir);
        File newsDir2 = new File(saveDir + "/dao/");
        File newsDir3 = new File(saveDir + "/service/");
        File newsDir4 = new File(saveDir + "/service/impl/");
        File newsDir5 = new File(saveDir + "/entity/");
        boolean flag = false;
    flag = (Boolean) (newsDir.exists() == false ? newsDir.mkdirs() : true);
    flag = (Boolean) (newsDir2.exists() == false ? newsDir2.mkdirs() : true);
    flag = (Boolean) (newsDir3.exists() == false ? newsDir3.mkdirs() : true);
    flag = (Boolean) (newsDir4.exists() == false ? newsDir4.mkdirs() : true);
    flag = (Boolean) (newsDir5.exists() == false ? newsDir5.mkdirs() : true);

        try (Writer out = new OutputStreamWriter(new FileOutputStream(
                fileNameDaoPath), "utf-8");
                Writer out2 = new OutputStreamWriter(new FileOutputStream(
                        fileNameServicePath), "utf-8");
                Writer out3 = new OutputStreamWriter(new FileOutputStream(
                        fileNameServiceImplPath), "utf-8");
                Writer out4 = new OutputStreamWriter(new FileOutputStream(
                        fileNameEntityPath), "utf-8");) {

            temp = cfg.getTemplate("Dao.ftl");
            temp.process(classPropties, out);
            System.out.println("------------DAO生成完毕-------------");

            temp = cfg.getTemplate("Service.ftl");
            temp.process(classPropties, out2);
            System.out.println("------------Service生成完毕-------------");

            temp = cfg.getTemplate("ServiceImpl.ftl");
            temp.process(classPropties, out3);
            System.out.println("------------ServiceImpl生成完毕-------------");

            temp = cfg.getTemplate("Object.ftl");
            temp.process(classPropties, out4);
            System.out.println("------------Entity生成完毕-------------");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        genateCode();
    }

2.2.2 模板文件.ftl的配置
将封装好的Map<String, Map<String, Object>>格式数据传入ftl
提一下:
顶级的MAP–key=Paramss
次一级的MAp—key0==Params0,key1==Params1,key…==Params….
参见前面put的代码

这里只举一个例子,模板文件名:entity.ftl,简单的实现。

import java.util.Date;
import com.pdsu.edu.domain.entity.${Paramss.Params0.classNameUpCase};
//通过mapKey.mapKey的方式获取设置的类名,因为每一个实体类中都有classNameUpCase
//这里取Params0这个key来用
public class ${Paramss.Params0.classNameUpCase} {
//以下为循环实体类的代码
<#list Paramss?values as value>
    //${value.comment}
    private ${value.type} ${value.column};
</#list>
<#list Paramss?values as value>
    public ${value.type} get${value.columnNameUpCase}(){
        return ${value.column};
    }
    public void set${value.columnNameUpCase} (${value.type} ${value.column}s){
        this.${value.column} = ${value.column}s;
    }
</#list>
}

2.2.3 用到的实体类代码
顺便使用了一下《effective JAVA》中提及的对象创建方式,方便入参,因为参数可能经常变化,table的还是属性比较多。

public class Params {
    private String tableName;
    private String column;
    private String columnNameUpCase;
    private String comment;
    private String type;
    private String keyName;
    private String defaultName;
    private String className;
    private String classNameUpCase;

    public Params(Build build) {
        this.className = build.className;
        this.classNameUpCase = build.classNameUpCase;
        this.tableName = build.tableName;
        this.column = build.column;
        this.comment = build.comment;
        this.type = build.type;
        this.keyName = build.keyName;
        this.defaultName = build.defaultName;
        this.columnNameUpCase = build.columnNameUpCase;
    }

    public static class Build {
        private String className;
        private String classNameUpCase;
        private String tableName;
        private String column;
        private String columnNameUpCase;
        private String comment;
        private String keyName;
        private String type;
        private String defaultName;

        public Build className(String classN) {
            className = classN;
            return this;
        }

        public Build classNameUpCase(String classNameUpC) {
            classNameUpCase = classNameUpC;
            return this;
        }

        public Build tableName(String tableN) {
            tableName = tableN;
            return this;
        }

        public Build columnNameUpCase(String columnNameUpCaseN) {
            columnNameUpCase = columnNameUpCaseN;
            return this;
        }
        public Build column(String columnN) {
            column = columnN;
            return this;
        }
        public Build key(String keyN) {
            keyName = keyN;
            return this;
        }
        public Build comment(String commentN) {
            comment = commentN;
            return this;
        }
        public Build type(String typeN) {
            type = typeN;
            return this;
        }
        public Build defaultName(String defaultN) {
            defaultName = defaultN;
            return this;
        }
        public Params buildParams() {
            return new Params(this);
        }
    }
    public String getTableName() {
        return tableName;
    }
    public String getColumn() {
        return column;
    }
    public String getColumnNameUpCase() {
        return columnNameUpCase;
    }
    public String getComment() {
        return comment;
    }
    public String getType() {
        return type;
    }
    public String getKeyName() {
        return keyName;
    }
    public String getDefaultName() {
        return defaultName;
    }
    public String getClassName() {
        return className;
    }
    public String getClassNameUpCase() {
        return classNameUpCase;
    }
}

以上就是本人套路Freemarker的全过程!

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值