一种基于数据库+模板渲染的代码生成器——表结构暂存与类设计

举报
KevinQ 发表于 2022/01/06 17:53:01 2022/01/06
【摘要】 若依中通过使用表“缓存”表与列数据,十分高明,值得学习!

接上篇

在上一篇文章《一种基于数据库+模板渲染的代码生成器——简介及数据库查询》中,我们介绍了代码生成器的基本概念以及常见的几种代码生成器,并阐述了通过mysql数据库中的information_schema库,查询数据库中的表结构、列结构等信息的方法。

本篇文章将继续阐述,查询出表结构与列结构后,如何将其逐步映射为编程语言Java中的类。

表与列结构暂存

在若依系统中,其实现代码生成分为两个步骤,第一步被称为“导入表”,即将所要生成代码的表的结构信息存储到到某几个指定表gen_tablegen_table_column中;之后再通过表中的数据渲染内容。

gen_tablegen_table_column其注释分别为:

表名 注释
gen_table 代码生成业务表
gen_table_column 代码生成业务表字段

先来看一下gen_table存储了哪些信息:

执行以下SQL:

SELECT
	COLUMN_NAME,
	COLUMN_COMMENT,
	DATA_TYPE
FROM
	information_schema.`COLUMNS`
WHERE
	TABLE_NAME = 'gen_table'
AND TABLE_SCHEMA = 'ry-vue'

查询结果如下图:

image-20220106165724085

再来看gen_table_column

SELECT
	COLUMN_NAME,
	COLUMN_COMMENT,
	DATA_TYPE
FROM
	information_schema.`COLUMNS`
WHERE
	TABLE_NAME = 'gen_table_column'
AND TABLE_SCHEMA = 'ry-vue'

执行结果如下:

image-20220106165833766

在Java中,分别按照表gen_tablegen_table_column构建两个实体对象,即Entity,以便后续通过mybatis等对其进行保存等相关操作。

我们截图部分源码代码(其所属位置位于若依项目:ruoyi-generator/src/main/java/com/ruoyi/generator/domain路径下):

public class GenTable extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    private Long tableId;

    /** 表名称 */
    @NotBlank(message = "表名称不能为空")
    private String tableName;

    /** 表描述 */
    @NotBlank(message = "表描述不能为空")
    private String tableComment;

    /** 关联父表的表名 */
    private String subTableName;
}
public class GenTableColumn extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    private Long columnId;

    /** 归属表编号 */
    private Long tableId;

    /** 列名称 */
    private String columnName;

    /** 列描述 */
    private String columnComment;
}

表名列名与类名字段名的转换

在获取到表结构与列结构数据后,其名称大多数是不符合类名创建规则的,需要做一个额外的转换,如下图:

表名与列名 Java类名与字段名
表名:sys_my_user MyUser
列名:user_name userName

对于列名,将其转换为驼峰命名法;对于表名,一是注意需要去掉某些指定前缀,二是将剩余部分转换为首字母大写的驼峰。

对于转换为驼峰的方式,我在若依系统源码中发现有两个不同的实现方式,供大家参考:

第一种,从字符串开头,通过大写标识依次拼接字符:


/*com.ruoyi.common.utils.StringUtils*/

private static final char SEPARATOR = '_';    
/**
* 转换为驼峰命名法
*/
public static String toCamelCase(String s)
    {
        if (s == null)
        {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);
            if (c == SEPARATOR)
            {
                upperCase = true;
            }
            else if (upperCase)
            {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            }
            else
            {
                sb.append(c);
            }
        }
        return sb.toString();
    }

第二种,按照下划线拆分原始字符串后,依次首字母大小,然后拼接:

/*com.ruoyi.common.utils.StringUtils*/

public static String convertToCamelCase(String name)
    {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty())
        {
            // 没必要转换
            return "";
        }
        else if (!name.contains("_"))
        {
            // 不含下划线,仅将首字母大写
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels)
        {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty())
            {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return result.toString();
    }

数据类型的转换

即数据库中定义的数据类型包括:varchar, int, datetime, decimal等等,这些都需要一一映射为Java中的相关对象,包括String, Integer, Date, BigDecimal等等。

暂存结果:

比如我们的表my_user,结构信息如下:

image-20220106172732427

经过转换,存储在gen_table以及gen_table_column中的数据为:

image-20220106172907984

image-20220106172927791

总结

我们便可不需要通过information_schema数据库查询信息,而仅需要通过这两个gen_表数据生成对应的类信息。通过其存储数据,我们也可以看到,表中存储了构建对象属性的类型、名称,这也便于后续直接生成对象,而不需要再次将其转换,减轻了一步操作的系统压力。

通过使用表“缓存”数据结构,的确是十分高明的方法,值得学习!

后续

那么又如何通过gen_tablegen_table_column中的数据生成想要的文件呢?我们之后会一一介绍。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。