【freemarker】【代码生成器】

这里写图片描述

数据模型的类

作用,是生成目标文件的数据模型.传入domain类,返回其数据模型的封装类

  • 构造器提供domain类的Class对象.
  • propNames:属性List
  • className:简单名的字符串(首字母大写)
  • basePackage:基础包的字符串

例:
传入一个类com.lwf.domain.Employee的Class对象,生成ci对象
* ci.basePackage= com.lwf
* ci.className= Employee
* ci.propNames =[属性名1.属性名2,属性名3]

public class ClassInfo {

    private String basePackage;  
    private String className;
    private List<String> propNames = new ArrayList<String>();

    //构造器
    public ClassInfo(Class<?> clazz) {
        //获取简单名 Employee
        this.className = clazz.getSimpleName();

        //获得基础包 com.lwf
        String pck = clazz.getPackage().getName();      
        pck = pck.substring(0, pck.lastIndexOf("."));
        this.basePackage = pck;

        //得到属性的名字的集合
        try {
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                    BaseDomain.class).getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                propNames.add(pd.getName());
            }
            Collections.reverse(propNames);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

生成目标文件

1.初始化方法
    //全局变量
    private Configuration cfg;

    public void initFreeMarker() throws Exception {
    //声明模版的目录
        cfg = new Configuration();
        File f = new File("src/main/java/com/xmg/codegen/template");
        cfg.setDirectoryForTemplateLoading(f);
    }
2.生成单个目标文件方法

genJavaFile(ci对象, 模版名,目标文件);
其中,目标文件用占位符的字符串 如"src/main/java/{0}/dao/I{1}DAO.java"

  • {0}=ci.basePackage(将点换成斜杠)
  • {1}=ci.className
private void genJavaFile(ClassInfo ci, String templateName,
            String filePathTemplate) throws Exception {
        //获取模版对象
        Template template = cfg.getTemplate(templateName);
        //将简单名首字母小写
        String uncap = ci.getClassName().substring(0, 1).toLowerCase()+ ci.getClassName().substring(1); 

        //获取完整的目标文件路径
        String filePath = MessageFormat.format( 
        filePathTemplate,                         //有占位符的路径
        ci.getBasePackage().replace(".", "/"),    //更换{0}
        ci.getClassName(),                         //更换{1}
         uncap);                                  //更换{2} 
        //若目标文件不存在则创建
        File f = new File(filePath);
        if (!f.exists()) {
            f.getParentFile().mkdirs();
        }

        //生成目标文件
        template.process(ci, new FileWriter(f));
}
3.将生成的dao,service,action.添加到Spring的bean中.

与创建文件区别,该方法是在原有的基础上添加代码
此时传入的目标文件路径是固定的.不用占位符

    private void mergeXml(ClassInfo ci, String templateName, String targetXml)
            throws Exception {
        Template template = cfg.getTemplate(templateName);
        StringWriter sw = new StringWriter();
        template.process(ci, sw);
        XmlUtil.mergeXML(new File(targetXml), sw.toString());
    }
//工具类的mergeXML方法
public class XmlUtil {

    public static void mergeXML(File xml, String appendingXml) throws Exception {
        SAXReader reader = new SAXReader();
        Document doc = reader.read(xml);

        Document flagment = DocumentHelper.parseText(appendingXml);
        Element flagEle = flagment.getRootElement();
        flagEle.setQName(new QName(flagEle.getName(), doc.getRootElement()
                .getNamespace()));
        if (flagEle.elements().size() > 0) {
            for (Object c : flagEle.elements()) {
                Element cel = (Element) c;
                cel.setQName(new QName(cel.getName(), flagEle.getNamespace()));
            }
        }
        doc.getRootElement().add(flagEle);
        XMLWriter writer = new XMLWriter(new FileWriter(xml));
        writer.write(doc.getRootElement());
        writer.close();
    }
}
4.批量生成的方法

调用上面两个方法(生成文件,添加bean),进行批量的代码生成.
传入一个Employee类的Class对象,需要生成的东西有:

创建的文件

  • DAO接口
  • DAO实现类
  • 映射文件
  • Service接口
  • Service 实现类
  • Action类
  • list.jsp
  • input.jsp

添加的bean

  • dao的bean
  • service的bean
  • action的bean
    public void initFreeMarker() throws Exception {
        cfg = new Configuration();
        File f = new File("src/main/java/com/xmg/codegen/template");
        cfg.setDirectoryForTemplateLoading(f);
    }

    public void genCode(Class<?> clazz) throws Exception {

        //获取数据模型的对象.ci中包含所有数据.
        ClassInfo ci = new ClassInfo(clazz);

        //1,合成DAO接口;
        genJavaFile(ci, "IDAO.ftl", "src/main/java/{0}/dao/I{1}DAO.java");

        //2,合成DAO实现;
        genJavaFile(ci, "DAOImpl.ftl",
                "src/main/java/{0}/dao/impl/{1}DAOImpl.java");

        //3,生成映射文件;
        genJavaFile(ci, "hbm.ftl", "src/main/java/{0}/domain/{1}.hbm.xml");

        //4,生成service接口;
        genJavaFile(ci, "IService.ftl",
                "src/main/java/{0}/service/I{1}Service.java");
        //5,生成service实现;
        genJavaFile(ci, "ServiceImpl.ftl",
                "src/main/java/{0}/service/impl/{1}ServiceImpl.java");
        //6,生成action;
        genJavaFile(ci, "Action.ftl", "src/main/java/{0}/action/{1}Action.java");
        //7,生成list.jsp
        genJavaFile(ci, "list.ftl",
                "src/main/webapp/WEB-INF/views/{2}/list.jsp");
        //8,生成input.jsp
        genJavaFile(ci, "input.ftl",
                "src/main/webapp/WEB-INF/views/{2}/input.jsp");
        //9,生成对应的配置文件片段,并且合并到对应的配置文件中;
        //9.1生成dao的配置文件
        mergeXml(ci, "daoxml.ftl", "src/main/resources/dao.xml");
        //9.2生成service的配置文件
        mergeXml(ci, "servicexml.ftl", "src/main/resources/service.xml");
        //9.3生成action的配置文件
        mergeXml(ci, "actionxml.ftl", "src/main/resources/action.xml");
    }
5.结果测试
    public static void main(String[] args) throws Exception {
        if (args.length == 1) {
            CodeGenMain main = new CodeGenMain();
            //初始化
            main.initFreeMarker();
            //取值domain的全限名字符串
            String clazzStr = args[0];
            //生成对应的代码
            Class<?> clazz = Class.forName(clazzStr);        
            main.genCode(clazz);
        }
    }

菜单栏Run→Run Configurations
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值