Напишите инструмент для создания классов сущностей базы данных.

Java

Напишите инструмент Java для создания классов сущностей из базы данных.

Заметки перед тем, как начать писать

Это всего лишь простой инструмент для создания java-файла в соответствии с результатом синтаксического анализа после анализа оператора построения таблицы базы данных. Это написано по двум причинам.

​ 1: Никто в проекте не пишет аннотации классов сущностей, аннотации полей, и существующие инструменты не могут автоматически добавлять их в файлы классов на основе аннотаций базы данных.

​ 2: Кажется, не так сложно написать его самостоятельно.

Поэтому я написал один сам.

Вот что используется при создании файла javafreemarker. использовалjdbcВ качестве инструмента для выполнения sql.

Этот проект выложен на github, адрес:GitHub.com/Хуан Цзяньсян60149632….

Используемые зависимости:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

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

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.45</version>
</dependency>

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

Получить все имена таблиц в базе данных

Если вы хотите создать java-файл в соответствии с оператором построения таблиц в базе данных, вы должны сначала узнать, какие таблицы находятся в базе данных. Итак, начните.

Информация о настройке базы данных

Прежде чем получить ссылку на базу данных, мы сначала пишем файл для сохранения различной информации о ссылке на базу данных.

создать новый файлconfig.xml

<xml>
    <jdbc.url></jdbc.url>
    <jdbc.username></jdbc.username>
    <jdbc.password></jdbc.password>
</xml>

jdbc.url: URL базы данных ссылок. Например: jdbc:mysql://127.0.0.1:3306/demo?useSSL=true

jdbc.username: Имя пользователя для базы данных.

jdbc.password: пароль для базы данных.

Это настроено.

Напишите класс инструмента для чтения xml: XmlUtils.java


import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Scanner;

/**
 * 读取xml
 */
public class XmlUtils {

    /**
     * 读取 Document
     *
     * @param xmlPath
     * @return
     */
    public static Document getConfigDocument(String xmlPath) {
        try {
            InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlPath);
            Scanner scanner = new Scanner(resourceAsStream);
            StringBuilder stringBuilder = new StringBuilder();
            while (scanner.hasNextLine()) {
                stringBuilder.append(scanner.nextLine()).append("\n");
            }
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilde = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilde.parse(new ByteArrayInputStream(stringBuilder.toString().getBytes()));
            return document;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Открыть ссылку на базу данных

//获取数据库配置信息
Document configXml = XmlUtils.getConfigDocument(CONFIG_PATH);
Element element = configXml.getDocumentElement();
String jdbcUrl = element.getElementsByTagName("jdbc.url").item(0).getTextContent();
String username = element.getElementsByTagName("jdbc.username").item(0).getTextContent();
String password = element.getElementsByTagName("jdbc.password").item(0).getTextContent();
//打开数据库链接
Connection conn = (Connection) DriverManager.getConnection(jdbcUrl, username, password);

После получения ссылки следующим шагом будет чтение данных таблицы в базе данных.

получить таблицу в базе данных

Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SHOW TABLES;");
while (resultSet.next()) {
	//这里就获取到了数据库中的所有的表的名称了。
	String tableName = resultSet.getString(1);
}

Получив здесь имя таблицы, вы можете, в свою очередь, получить оператор построения таблицы и проанализировать оператор построения таблицы.

Причина, по которой здесь используется метод разбора оператора построения таблицы, заключается в том, что аннотационная информация может быть получена более полно. При использовании другого метода аннотации таблицы не могут быть получены все время (забыл сказать о другом методе~).

получить инструкцию сборки

Вот сращивание sql, а потом его выполнить. Вот код:

Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("show CREATE TABLE 表名称");
while (resultSet.next()) {
	//这里就得到了表的建表语句
	String createTableSql = resultSet.getString(2);
}

После этого шага мы полностью получили все операторы построения таблиц в базе данных. Следующим шагом является анализ оператора создания таблицы и его использование для создания классов сущностей.

Создать анализ оператора таблицы

создать таблицу sql

Ниже приведено выполнение sqlshow create table userрезультат:

CREATE TABLE `user` (                                                            
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',                         
  `name` varchar(225) DEFAULT NULL COMMENT '用户名',                             
  `create_date` datetime DEFAULT NULL,                                           
  `status` int(11) DEFAULT NULL,                                                 
  `age` int(11) DEFAULT NULL COMMENT '年龄',                                     
  `mark` varchar(225) DEFAULT NULL,                                              
  PRIMARY KEY (`id`)                                                             
) ENGINE=InnoDB AUTO_INCREMENT=2104778081 DEFAULT CHARSET=latin1 COMMENT='用户表'          

Здесь видно, что имя создаваемого класса сущностей находится в первой строкеCREATE TABLEВ середине два последних символа **`**, чтобы мы могли вынести имя таблицы через регулярные выражения, а затем преобразовать его в нужное нам имя класса. Во-первых, давайте напишем метод для извлечения данных с помощью регуляризации, Ниже приведен код:

обычный код

    /**
     * 根据正则查找
     *
     * @param sql
     * @param pattern
     * @param group
     * @return
     */
    static String getByPattern(String sql, String pattern, int group) {
        Pattern compile = Pattern.compile(pattern);
        Matcher matcher = compile.matcher(sql);
        while (matcher.find()) {
            return matcher.group(group);
        }
        return null;
    }

Теперь начните извлекать имя таблицы из оператора создания таблицы (хотя я уже знаю это, когда получаю все таблицы в базе данных, но нет проблем написать его один раз, правильно~~~), следующее код:

Получить имя таблицы

    /**
     * 获得表的名称
     *
     * @param sql
     * @return
     */
    public static String getTableName(String sql) {
        return getByPattern(sql, "CREATE TABLE `(.*)`", 1);
    }

Здесь имя таблицы было вынесено. Следующим шагом будет получение комментариев к таблице, здесь мы получаем комментарии к таблице. Вот код:

Извлечь комментарии к таблице

    public static String getTableComment(String sql) {
        return getByPattern(sql, "\\) .* COMMENT='(.*)'", 1);
    }

Теперь начните получать информацию об идентификаторе.

получить идентификатор

Для получения id по-прежнему хорошо использовать обычный код, код выглядит следующим образом:

public static String getId(String sql) {
    return getByPattern(sql, "PRIMARY KEY \\(`(.*)`\\)", 1);
}

Поскольку в исходном выражении есть пара круглых скобок, внешние круглые скобки здесь экранируются. Затем начните извлекать поля, типы полей и комментарии к полям в базе данных.

поле, тип поля, комментарий к полю

Сначала выньте SQL, связанный с полем в операторе построения таблицы.

21 января 2019 г., изменено:

Неожиданно в некоторых таблицах отсутствует id, что приводит к ошибке после выполнения следующего кода Изменить решение конца.

    /**
     * 获取建表语句中和字段相关的sql
     *
     * @param sql
     * @return
     */
    public static List<String> getColumnSqls(String sql) {
        List<String> lines = new ArrayList<>();
        Scanner scanner = new Scanner(sql);
        boolean start = false;
        while (scanner.hasNextLine()) {
            String nextLine = scanner.nextLine();
            if (nextLine.indexOf("CREATE TABLE") != -1) {
                start = true;
                continue;
            }
            //没想到有的表没有id /(ㄒoㄒ)/~~
            if (nextLine.indexOf("PRIMARY KEY") != -1 || nextLine.indexOf("ENGINE=") != -1) {
                start = false;
                continue;
            }
            if (start) {
                lines.add(nextLine);
            }
        }
        return lines;
    }

Результат работы здесь:

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',                         
  `name` varchar(225) DEFAULT NULL COMMENT '用户名',                             
  `create_date` datetime DEFAULT NULL,                                           
  `status` int(11) DEFAULT NULL,                                                 
  `age` int(11) DEFAULT NULL COMMENT '年龄',                                     
  `mark` varchar(225) DEFAULT NULL, 

Это также получает всю информацию, связанную с полем в таблице.Далее, давайте получим имя поля:

Получить имена столбцов, комментарии, типы данных

List<String> columns = SqlUtils.getColumnSqls(sql);
for (String oneLine : columns) {
    System.out.println(oneLine);
    String columnName = SqlUtils.getByPattern(oneLine, "`(.*)`", 1);
    String comment = SqlUtils.getByPattern(oneLine, "COMMENT '(.*)'", 1);
    String columnType = SqlUtils.getByPattern(oneLine, "`" + columnName + "` ([A-Za-z]*)", 1);
    System.out.printf("名称:%-20s 类型:%-20s 注释:%-20s \n", columnName, columnType, comment);
}

Выходной результат:

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',                         
名称:id                   类型:int                  注释:用户id                 
  `name` varchar(225) DEFAULT NULL COMMENT '用户名',                             
名称:name                 类型:varchar              注释:用户名                  
  `create_date` datetime DEFAULT NULL,                                           
名称:create_date          类型:datetime             注释:null                 
  `status` int(11) DEFAULT NULL,                                                 
名称:status               类型:int                  注释:null                 
  `age` int(11) DEFAULT NULL COMMENT '年龄',                                     
名称:age                  类型:int                  注释:年龄                   
  `mark` varchar(225) DEFAULT NULL,                                              
名称:mark                 类型:varchar              注释:null

На данный момент я получил все необходимые данные из оператора построения таблицы и начну использовать эти данные для создания java-файлов.

Начните создавать java-файлы на основе данных, полученных выше.

Наконец начал создавать java файлы.

Но ~ при создании java файла нужно сначала обработать данные, полученные ранее, и преобразовать формат в sql в формат в java. Например, имена атрибутов, типы данных, имена классов и т. д., начните сейчас~

Преобразование имен таблиц в соответствующие имена классов

Это соглашение об именах с заглавной буквы в верблюжьем регистре. Например, будетuser_logилиUSER_LOGКонвертировать в UserLog.

Мы можем написать:

    /**
     * 类名称转换
     *
     * @param tableName
     * @return
     */
    public static String entityName(String tableName) {
        String lowerCaseName = tableName.toLowerCase();
        StringBuilder newName = new StringBuilder();
        char[] chars = lowerCaseName.toCharArray();
        boolean change = false;
        for (int i = 0; i < chars.length; i++) {
            char aChar = chars[i];
            if (aChar == '_' && !change) {
                change = true;
                continue;
            }
            //首字母大写
            if (i == 0) {
                aChar = Character.toUpperCase(aChar);
            }
            if (change) {
                aChar = Character.toUpperCase(aChar);
                change = false;
            }
            newName.append(aChar);
        }
        return newName.toString();
    }

Это дает имя класса, который нам нужен.

Преобразование имени поля в имя свойства в java

Вот, чтобы удалить заглавную букву предыдущей операции.Ниже приведен код:

    /**
     * 属性名称转换
     *
     * @param name
     * @return
     */
    public static String fieldName(String name) {
        name = name.toLowerCase();
        StringBuilder newName = new StringBuilder();
        char[] chars = name.toCharArray();
        boolean change = false;
        for (int i = 0; i < chars.length; i++) {
            char aChar = chars[i];
            if (aChar == '_' && !change) {
                change = true;
                continue;
            }
            if (change) {
                aChar = Character.toUpperCase(aChar);
                change = false;
            }
            newName.append(aChar);
        }
        return newName.toString();
    }

Следующим шагом является преобразование типа данных в sql в тип данных в java.

преобразование типа данных sql

Здесь карта используется для создания отображения, и вы можете изменить ее самостоятельно, если у вас есть свои особые требования.


public class ColumnFieldTypeMapping {

    private Map<String, Class> sqlFieldTypeMapping = new HashMap<>();

    {
        sqlFieldTypeMapping.put("VARCHAR", String.class);
        sqlFieldTypeMapping.put("CHAR", String.class);
        sqlFieldTypeMapping.put("TEXT", String.class);
        sqlFieldTypeMapping.put("MEDIUMTEXT", String.class);
        sqlFieldTypeMapping.put("LONGTEXT", String.class);
        sqlFieldTypeMapping.put("TINYTEXT", String.class);
        sqlFieldTypeMapping.put("BIT", Boolean.class);

        sqlFieldTypeMapping.put("INT", int.class);
        sqlFieldTypeMapping.put("BIGINT", long.class);
        sqlFieldTypeMapping.put("DOUBLE", double.class);
        sqlFieldTypeMapping.put("TINYINT", int.class);
        sqlFieldTypeMapping.put("FLOAT", float.class);
        sqlFieldTypeMapping.put("DECIMAL", BigDecimal.class);

        sqlFieldTypeMapping.put("INT UNSIGNED", int.class);
        sqlFieldTypeMapping.put("BIGINT UNSIGNED", int.class);
        sqlFieldTypeMapping.put("DECIMAL UNSIGNED", BigDecimal.class);

        sqlFieldTypeMapping.put("DATETIME", Date.class);
        sqlFieldTypeMapping.put("TIME", Date.class);
        sqlFieldTypeMapping.put("DATE", Date.class);
        sqlFieldTypeMapping.put("TIMESTAMP", Date.class);
    }

    /**
     * 根据sql数据类型获取Java数据类型
     *
     * @param columnType
     * @return
     */
    public Class getFieldType(String columnType) {
        Class aClass = sqlFieldTypeMapping.get(columnType);
        if (aClass == null) {
            return sqlFieldTypeMapping.get(columnType.toUpperCase());
        }
        return null;
    }
}

На данный момент вся информация, необходимая для создания java-файла, получена.

На данный момент нам нужно собрать их и поместить в freemarker, чтобы проанализировать и сгенерировать содержимое в java-файле.

Параметры сборки

Здесь, возможно, я буду использовать этот код для других целей в будущем, поэтому я создал два класса, один из которыхClassModel.java,одинEntityModel.java.

EntityModel наследует ClassModel. Мы в основном используемEntityModel.java. Вот код:


import java.util.*;

/**
 * 用于生成java Entity文件的类
 */
public class ClassModel {

    /**
     * java 中不需要引包的类型
     */
    private static List<Class> baseClass = Arrays.asList(
            int.class,
            double.class,
            float.class,
            long.class,
            short.class,
            byte.class,
            char.class,
            boolean.class,
            String.class
    );

    /**
     * 类注释
     */
    private String classDoc;

    /**
     * 类名
     */
    private String className;

    /**
     * 类 包名
     */
    private String packageName;

    /**
     * K:属性名称
     * V:属性类型
     */
    private Map<String, Class> fields = new HashMap<>();

    /**
     * 属性的注释
     */
    private Map<String, String> fieldDoc = new HashMap<>();
    ;

    private List<Class> imports = new ArrayList<>();

    /**
     * 添加需要导入的包
     *
     * @param importClass
     */
    public void addImport(Class importClass) {
        if (baseClass.indexOf(importClass) != -1) {
            return;
        }
        if (imports.indexOf(importClass) == -1) {
            imports.add(importClass);
        }
    }

    /**
     * 添加属性
     *
     * @param fieldName  属性名称
     * @param fieldClass 属性类型
     */
    public void addfield(String fieldName, Class fieldClass) {
        if (!fields.containsKey(fieldName)) {
            fields.put(fieldName, fieldClass);
        }
    }

    /**
     * 添加属性注释
     *
     * @param fieldName 属性名称
     * @param fieldDoc  属性注释
     */
    public void addfieldDoc(String fieldName, String fieldDoc) {
        if (!this.fieldDoc.containsKey(fieldName)) {
            this.fieldDoc.put(fieldName, fieldDoc);
        }
    }

    public List<Class> getImports() {
        return imports;
    }

    public void setImports(List<Class> imports) {
        this.imports = imports;
    }

    public String getClassDoc() {
        return classDoc;
    }

    public void setClassDoc(String classDoc) {
        this.classDoc = classDoc;
    }

    public String getClassName() {
        return className;
    }

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

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public Map<String, Class> getFields() {
        return fields;
    }

    public void setFields(Map<String, Class> fields) {
        this.fields = fields;
    }

    public Map<String, String> getFieldDoc() {
        return fieldDoc;
    }

    public void setFieldDoc(Map<String, String> fieldDoc) {
        this.fieldDoc = fieldDoc;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("{");
        sb.append("            \"classDoc\"=\"").append(classDoc).append('\"');
        sb.append(",             \"className\"=\"").append(className).append('\"');
        sb.append(",             \"packageName\"=\"").append(packageName).append('\"');
        sb.append(",             \"fields\"=").append(fields);
        sb.append(",             \"fieldDoc\"=").append(fieldDoc);
        sb.append(",             \"imports\"=").append(imports);
        sb.append('}');
        return sb.toString();
    }
}

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

/**
 * 数据库映射
 */
public class EntityModel extends ClassModel {

    /**
     * 数据库名称
     */
    private String tableName;

    /**
     * 数据库中的Id字段名称
     */
    private List<String> idColumnNames = new ArrayList<>();

    /**
     * 类属性名对应数据库字段映射
     * key: class 属性名称
     * value:数据库字段名
     */
    private Map<String, String> fieldSqlName = new HashMap<>();

    /**
     * 添加class 属性映射和 数据库 字段映射
     *
     * @param fieldName
     * @param sqlName
     */
    public void addfieldSqlName(String fieldName, String sqlName) {
        if (!fieldSqlName.containsKey(fieldName)) {
            fieldSqlName.put(fieldName, sqlName);
        }
    }

    /**
     * 添加id字段名
     *
     * @param idColumnName
     */
    public void addIdColumnName(String idColumnName) {
        idColumnNames.add(idColumnName);
    }

    public String getTableName() {
        return tableName;
    }

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

    public Map<String, String> getFieldSqlName() {
        return fieldSqlName;
    }

    public void setFieldSqlName(Map<String, String> fieldSqlName) {
        this.fieldSqlName = fieldSqlName;
    }

    public List<String> getIdColumnNames() {
        return idColumnNames;
    }

    public void setIdColumnNames(List<String> idColumnNames) {
        this.idColumnNames = idColumnNames;
    }
}

Здесь собираются данные, полученные из базы данных, и с помощью freemarker можно сгенерировать содержимое файла Java. Вот код:

/**
 * 根据建表语句组装EntityModel
 *
 * @param createTableSql
 * @return
 */
EntityModel makeModelBySql(String createTableSql) {
    Formatter formatter = new Formatter();
    EntityModel model = new EntityModel();
    String tableComment = SqlUtils.getTableComment(createTableSql);
    String tableName = SqlUtils.getTableName(createTableSql);
    String id = SqlUtils.getId(createTableSql);
    model.addIdColumnName(id);
    model.setClassName(NameConvert.entityName(tableName));
    model.setTableName(tableName);
    //注释是null的时候用数据库表名作为注释
    model.setClassDoc(tableComment == null ? tableName : tableComment);
    List<String> line = SqlUtils.getColumnSqls(createTableSql);
    for (String oneLine : line) {
        String columnName = SqlUtils.getByPattern(oneLine, "`(.*)`", 1);
        String comment = SqlUtils.getByPattern(oneLine, "COMMENT '(.*)'", 1);
        String columnType = SqlUtils.getByPattern(oneLine, "`" + columnName + "` ([A-Za-z]*)", 1);
        String fieldName = NameConvert.fieldName(columnName);
        Class fieldClass = columnFieldTypeMapping.getFieldType(columnType);
        if (fieldClass == null) {
            formatter.format("table:%s columnName:%s sql类型:%s 没有映射类型", tableName, columnName, columnType);
            throw new UnsupportedOperationException(formatter.toString());
        }
        model.addfield(fieldName, fieldClass);
        //字段注释是null的时候用数据库字段名作为注释
        model.addfieldDoc(fieldName, comment == null ? columnName : comment);
        model.addfieldSqlName(fieldName, columnName);
        model.addImport(fieldClass);
    }
    return model;
}

Такой параметр нам нужен собран. Теперь начните писать код для freemarker.

класс инструмента freemarker

Используется для загрузки шаблонов freemarker и параметров обработки в шаблонах.FreeMarkerUtils.java, код показан ниже:


import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

import java.io.StringWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.Scanner;

public class FreeMarkerUtils {

    /**
     * freemarker工具,
     *
     * @param subjectParams
     * @param templetPath
     * @return
     * @throws Exception
     */
    public static String getJavaClass(Object subjectParams, String templetPath) throws Exception {
        StringTemplateLoader loader = new StringTemplateLoader();
        Scanner scanner = new Scanner(Thread.currentThread().getContextClassLoader().getResourceAsStream(templetPath));
        StringBuilder builder = new StringBuilder();
        while (scanner.hasNext()) {
            builder.append(scanner.nextLine()).append("\n");
        }
        String name = System.currentTimeMillis() + "";
        loader.putTemplate(name, builder.toString());
        //第一步:实例化Freemarker的配置类
        Configuration conf = new Configuration();
        conf.setObjectWrapper(new DefaultObjectWrapper());
        conf.setLocale(Locale.CHINA);
        conf.setDefaultEncoding("utf-8");
        conf.setTemplateLoader(loader);
        //处理空值为空字符串
        conf.setClassicCompatible(true);
        Template template = conf.getTemplate(name);
        Writer out = new StringWriter(2048);
        template.process(subjectParams, out);
        String javaClass = out.toString();
        return javaClass;
    }
}

Теперь, когда у нас есть класс инструмента, мы не можем сразу начать генерировать java-файлы, потому что нам нужно продолжать устанавливать java-пакет и путь к генерируемым файлам.В это время мы можем изменить ранее написанныйconfig.xml

Изменить config.xml

<xml>
    <jdbc.url></jdbc.url>
    <jdbc.username></jdbc.username>
    <jdbc.password></jdbc.password>
    <basePath>/home/hjx/work/demo/src/main/java</basePath>
    <entityPackage>top.hejiaxuan.demo.entity</entityPackage>
</xml>

Здесь добавляются два параметра:basePathа такжеentityPackage. Один — это путь к файлу для создания java, а другой — имя пакета java-файла.

Затем мы пишем класс инструмента, который записывает файлFileUtils.java

Напишите FileUtils.java


import java.io.*;

public class FileUtils {

    /**
     * 写入文件
     *
     * @param path    文件路径
     * @param content 文件内容
     */
    public static void write(String path, String content) {
        File file = new File(path);
        File parentFile = file.getParentFile();
        try {
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(content);
            fileWriter.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Таким образом, все готово, осталось только сгенерировать файл. Давайте начнем сейчас~~~

Начать генерацию java-файлов

Перед генерацией файла нам также нужно поставитьbasePath,entityPackageУберите его из конфигурационного файла, я не буду писать этот шаг~~

static final String DOT = ".";

static final String FILE_TYPE = ".java";

static final String ENTITY_TEMPLET_PATH = "EntityTemp.ftl";

/**
 * 用于生成一个类文件
 *
 * @param entityModel
 * @return
 */
boolean makeOneClass(EntityModel entityModel) {
    entityModel.setPackageName(entityPackage);
    String filePath = basePath + "/" + entityPackage.replace(DOT, "/") + "/" + entityModel.getClassName() + FILE_TYPE;
    try {
        String javaClassString = FreeMarkerUtils.getJavaClass(entityModel, ENTITY_TEMPLET_PATH);
        FileUtils.write(filePath, javaClassString);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

Ладно~~~ Готово.

эм~~~

Кажется, чего-то не хватает

Файл шаблона не выпущен~~~

написатьEntityTemp.ftl

package ${packageName};

<#--导入的包-->
<#list imports as import>
import ${import.name};
</#list>

<#--类名-->
<#if classDoc?length gt 0>
/**
 * ${classDoc}
 * @author hejiaxuan
 */
</#if>
public class ${className} {

<#--属性名称-->
<#list fields?keys as key>
    <#assign  fieldDocStr = fieldDoc[key]>
    <#if fieldDocStr?length gt 0>
    /**${fieldDocStr}*/
    </#if>
    <#if idColumnNames?seq_contains(fieldSqlName[key])>
    </#if>
    private ${fields[key].simpleName} ${key};

</#list>
<#list fields?keys as key>
    <#assign  fieldClass = fields[key].simpleName>
<#--setter-->
    public void set${key?cap_first}(${fieldClass} ${key}) {
        this.${key} = ${key};
    }

<#--getter-->
    public ${fieldClass} <#if fieldClass="boolean">is<#else>get</#if>${key?cap_first}() {
        return this.${key};
    }

</#list>

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("[");
<#list fields?keys as key>
        sb.append("${key}:").append(${key}).append(";    ");
</#list>
        sb.append("]");
        return sb.toString();
    }
}

В конце концов

​ Здесь я просто разместил некоторые фрагменты кода для использования, а не писал все коды. По сути, написание инструментов — это процесс медленной реализации собственных идей, если есть идеи, то все очень просто.

​ Если кому-то нужен полный код проекта, пожалуйста, перейдите по ссылкеGitHub.com/Хуан Цзяньсян60149632…Убедитесь сами.

над

другие

Если вы считаете, что то, что я написал, нормально, пожалуйста, прочитайте другие статьи ^_^

Напишите свой собственный фреймворк mvc