The source code is for testing only and should not be used commercially. The source code comes from the Internet. If there is any infringement, please contact me to remove it.
Java代码生成器的原理

1. preface

I wrote an article aboutMybatis Plus Code GeneratorIn my article, many students privately asked me how this code generator works and why I need to use some template engines, so today I will explain the code generator process.

2. Usage scenarios for code generators

We have a lot of boilerplate code in our coding. The format is relatively fixed, the structure is relatively stable with the iteration of the project, and the quantity is huge. If we write too much of this code, it will not have any technical content. In this case, the code generator can effectively improve our efficiency, but it is not suitable to use a code generator in other situations.

3. Code generator production process

First of all, we need to make a template and extract the fixed format of the boilerplate code. Then bind dynamic attributes to the template, just like filling in the blanks. So the template engine is the most suitable in this process. We use the template engine's syntax to dynamically parse the data into static templates, and then export it to the corresponding file in programming.

In addition, the template engine has a rich instruction set for binding data, which allows us to dynamically bind data to templates based on conditions. toFreemarkerTake an example:

ternary expression:

${true ? 'checked': ''}

There is also the traversal list we will use later:

<#list  fields as field>
    private ${field.fieldType}  ${field.fieldName};
</#list>

The template engines we commonly use in Java development are:FreemarkerVelocityThymeleaf , withWebThe usage scenarios of the popular template engine that separates the front and back ends in development are being compressed, but it is still a useful technology.

4. Code generator demonstration

Next, we useFreemarkerWrite a simple code generator for an example to generatePOJOClass. need to introduceFreemarkerdependence.

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

4.1 formwork fabrication

POJOThe structure can be divided into the following parts:

Java类的基本结构

java.lang Packages do not need to be imported.

So encapsulate these rules into configuration classes:

public class JavaProperties {
    // 包名
    private final String pkg;
    // 类名
    private final String entityName;
    // 属性集合  需要改写 equals hash 保证名字可不重复 类型可重复
    private final Set<Field> fields = new LinkedHashSet<>();
    // 导入类的不重复集合
    private final Set<String> imports = new LinkedHashSet<>();


    public JavaProperties(String entityName, String pkg) {
        this.entityName = entityName;
        this.pkg = pkg;
    }

    public void addField(Class<?> type, String fieldName) {
        // 处理 java.lang
        final String pattern = "java.lang";
        String fieldType = type.getName();
        if (!fieldType.startsWith(pattern)) {
           // 处理导包
            imports.add(fieldType);
        }
        Field field = new Field();
        // 处理成员属性的格式
        int i = fieldType.lastIndexOf(".");
        field.setFieldType(fieldType.substring(i + 1));
        field.setFieldName(fieldName);
        fields.add(field);
    }

    public String getPkg() {
        return pkg;
    }


    public String getEntityName() {
        return entityName;
    }


    public Set<Field> getFields() {
        return fields;
    }

    public Set<String> getImports() {
        return imports;
    }


    /**
     * 成员属性封装对象.
     */
    public static class Field {
        // 成员属性类型
        private String fieldType;
        // 成员属性名称
        private String fieldName;

        public String getFieldType() {
            return fieldType;
        }

        public void setFieldType(String fieldType) {
            this.fieldType = fieldType;
        }

        public String getFieldName() {
            return fieldName;
        }

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

        /** 
         * 一个类的成员属性 一个名称只能出现一次 
         * 我们可以通过覆写equals hash 方法 然后放入Set
         * 
         * @param o 另一个成员属性
         * @return 比较结果
         */
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Field field = (Field) o;
            return Objects.equals(fieldName, field.fieldName);
        }

        @Override
        public int hashCode() {
            return Objects.hash(fieldType, fieldName);
        }
    }

}

Then there is the static templateentity.ftl

package ${pkg};

<#list  imports as impt>
import ${impt};
</#list>

/**
 * the ${entityName} type
 * @author felord.cn
 */
public class ${entityName} {

<#list  fields as field>
    private ${field.fieldType}  ${field.fieldName};
</#list>

}

Here we useFreemarkerThe syntax for binding data, such asListIterative rendering.

4.2 Generator writing

FreemarkerConfigure and obtain template objects through declarationsfreemarker.template, the objectprocessThe method can bind dynamic data into a template and export it as a file, and finally implements a code generator. The core code is as follows:

/**
 * Simple code generator.
 *
 * @param rootPath       maven's java directory
 * @param templatePath   Folder where templates are stored
 * @param templateName   the name of the template
 * @param javaProperties requires encapsulation of the rendered object
 * @throws IOException       the io exception
 * @throws TemplateException the template exception
 */
public static void autoCodingJavaEntity(String rootPath,
                                         String templatePath,
                                         String templateName,
                                         JavaProperties javaProperties) throws IOException, TemplateException {

    // freemarker configuration
    Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);

    configuration.setDefaultEncoding("UTF-8");
    //Specify the path to the template
    configuration.setDirectoryForTemplateLoading(new File(templatePath));
    //Get the template under the path according to the template name
    Template template = configuration.getTemplate(templateName);
    //Handle path issues
    final String ext = ".java";
    String javaName = javaProperties.getEntityName().concat(ext);
    String packageName = javaProperties.getPkg();

    String out = rootPath.concat(Stream.of(packageName.split("\\."))
            .collect(Collectors.joining("/", "/", "/" + javaName)));

     //Define an output stream to export code files
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(out));
     // freemarker engine exports dynamic data-bound templates into files
    template.process(javaProperties, outputStreamWriter);

}

You can generate one by executing the following codeUserEntitythePOJO

//The path is adjusted according to the characteristics of your project
String rootPath = "C:\\Users\\felord\\IdeaProjects\\codegenerator\\src\\main\\java";
String packageName = "cn.felord.code";
String templatePath = "C:\\Users\\felord\\IdeaProjects\\codegenerator\\src\\main\\resources\\templates";
String templateName = "entity.ftl";


JavaProperties userEntity = new JavaProperties("UserEntity", packageName);

userEntity.addField(String.class, "username");
userEntity.addField(LocalDate.class, "birthday");
userEntity.addField(LocalDateTime.class, "addTime");
userEntity.addField(Integer.class, "gender");
userEntity.addField(Integer.class, "age");


autoCodingJavaEntity(rootPath, templatePath, templateName, userEntity);

Is the generated effect similar to the handwritten one:

生成的Java POJO

5. summary

This is the mechanism of most code generators, and I hope it can answer some netizens 'questions.

read more
Resource download
PriceFree
The use is limited to testing, experiments, and research purposes. It is prohibited for all commercial operations. This team is not responsible for any illegal behavior of users during use. Please self-test all source codes! There is no guarantee of the integrity and validity of your source code. All source code is collected from the entire network
Original link:https://bcbccb.cn/en/4630.html, please indicate the source for reprinting. Disclaimer: This resource has not been authorized by the original rights holder and is not commercially available. It can only be used to learn and analyze the underlying code, CSS, etc., and is prohibited for commercial purposes. Any relevant disputes and legal liabilities arising from unauthorized commercial use shall be fully borne by the user. Everyone is responsible to support genuine copies. Please delete them within 24 hours after downloading. Thank you for your support!
1

Comments0

经典海外游戏源码海外高端娱乐游戏源码全开源 带教程
Classic overseas game source code overseas high-end entertainment game source code fully open source with tutorial
Someone bought it 1 minute ago Go and have a look

Site Announcements

The source code (theme/plug-in/application source code) and other resources provided by this site are only for learning and exchange

Commercial use is prohibited, otherwise all consequences will be borne by the downloading user!

Some resources are collected or copied online. If they infringe on your legitimate rights and interests, please write to us.

Currently, members have a big reward, and the current price for a lifetime member is 299 gold coins.Recent price adjustments

Join quickly, opportunities wait for no one! immediately participated in

Captcha

Fast login to social accounts

en_USEnglish