根据数据字典自动生成 Java 枚举类

1,237 阅读1分钟

先看最终效果

原始字典数据

image.png

生成的枚举类

## 流程
  1. 配置数据库连接信息,百度翻译API信息,字典 dict_id,以及其它配置
  2. 调用原生JDBC方法查询数据库,构造Java对象
  3. 调用百度翻译接口,得到字典 label 对应的英文,并处理成大写下划线的格式
  4. 构造模板数据,匹配模板中定义的字段
  5. 生成枚举类

字典相关表结构

字典类型 字典数据

image.png

核心代码

vm 模板

package ${package};

import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
 * <p>
 * $!{comment}
 * </p>
 *
 * @author Universe
 */
@RequiredArgsConstructor
@Getter
public enum ${name} {
## ----------  BEGIN 字段循环遍历  ----------
#foreach($field in ${fields})
    /**
     * ${field.label}
     */
    ${field.enumName}("${field.label}", "${field.value}"),
#end
    ;
    private final String label;
    private final String value;

}

JDBC 数据库查询

public static List<BiSysDictDataEntity> selectDictDataById(Integer dictId) {
    String sql = "select data_label,data_value from BI_SYS_DICT_DATA where dict_id = ?";
    PreparedStatement preparedStatement = null;
    List<BiSysDictDataEntity> list = new ArrayList<>();
    try {
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, dictId);
        ResultSet resultSet = preparedStatement.executeQuery();

        while (resultSet.next()) {
            BiSysDictDataEntity entity = new BiSysDictDataEntity();
            entity.setDataLabel(resultSet.getString("data_label"));
            entity.setDataValue(resultSet.getString("data_value"));
            list.add(entity);
        }
    } catch (SQLException e) {
        log.error(e.getMessage(), e);
    } finally {
        try {
            assert preparedStatement != null;
            preparedStatement.close();
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
    }
    return list;
}

翻译和处理

/**
 * 中文翻译成应为大写+下划线
 *
 * @param word 带翻译中文
 * @return 翻译后的枚举格式字段
 */
public static String translate(String word) {
    // 过滤掉字典 label 中的特殊字符
    word = word.replaceAll("[()|/()]" , "" );
    // 调用翻译接口
    TransApi api = new TransApi(APP_ID, SECURITY_KEY);
    String transResult = api.getTransResult(word, "auto" , "en" );
    log.info("transResult : {} " , transResult);
    TranslateResult translateResult = JSON.parseObject(transResult, TranslateResult.class);
    try {
        // 普通接口 访问频率受限,休眠1s
        Thread.sleep(1000);
        return translateResult.getTransResult().get(0).getDst().toUpperCase().replace(" " , "_" );
    } catch (Exception e) {
        log.error(e.getMessage());
        return word.toUpperCase();
    }
}

Main 方法

public static void main(String[] args) throws IOException {
    // 查询字典类型
    BiSysDictTypeEntity dictType = selectDictTypeById(DICT_ID);
    log.debug("dictType : {} " , dictType);
    // 查询字典数据
    List<BiSysDictDataEntity> list = selectDictDataById(DICT_ID);
    log.debug("list : {} " , list);
    // 数据转化,翻译,构造
    List<Map<String, String>> fields = new ArrayList<>();
    for (BiSysDictDataEntity entity : list) {
        fields.add(build(entity.getDataLabel(), entity.getDataValue(),
                translate(entity.getDataLabel())));
    }
    //设置velocity资源加载器
    Properties prop = new Properties();
    prop.put("file.resource.loader.class" , "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
    Velocity.init(prop);
    //创建Velocity容器
    VelocityContext context = new VelocityContext();
    context.put("package" , PACKAGE_PARENT);
    context.put("comment" , dictType.getDictRemark());
    context.put("name" , dictType.getDictName().toUpperCase());
    context.put("fields" , fields);
    //加载模板
    Template tpl = Velocity.getTemplate("templates/enum.java.vm" , "UTF-8" );
    String projectPath = System.getProperty("user.dir" );
    FileWriter fw = new FileWriter(projectPath + File.separator + OUT_PATH
            + File.separator + PACKAGE_PARENT.replace("." , "/" )
            + File.separator + dictType.getDictName().toUpperCase() + ".java" );
    //合并数据到模板
    tpl.merge(context, fw);
    //释放资源
    fw.close();
}

改进方向

  1. 目前的整个代码风格是面向过程,不够优雅
  2. 百度 API 限制 QPS=1,可以优化为一次性传入全部中文并切割处理翻译后的结果
  3. ...

参考文档

百度翻译 API 文档:api.fanyi.baidu.com/product/111