接上篇
在上一篇文章《一种基于数据库+模板渲染的代码生成器——简介及数据库查询》中,我们介绍了代码生成器的基本概念以及常见的几种代码生成器,并阐述了通过mysql数据库中的information_schema
库,查询数据库中的表结构、列结构等信息。
本篇文章将继续阐述,查询出表结构与列结构后,如何将其逐步映射为编程语言Java中的类及对象。
表与列结构暂存
在若依系统中,其实现代码生成分为两个步骤,第一步被称为“导入表”,即将所要生成代码的表的结构信息存储到到某几个指定表gen_table
、gen_table_column
中。
其注释分别为:
表名 |
注释 |
gen_table |
代码生成业务表 |
gen_table_column |
代码生成业务表字段 |
先来看一下gen_table
存储了哪些信息:
执行以下SQL:
1 2 3 4 5 6 7 8 9
| SELECT COLUMN_NAME, COLUMN_COMMENT, DATA_TYPE FROM information_schema.`COLUMNS` WHERE TABLE_NAME = 'gen_table' AND TABLE_SCHEMA = 'ry-vue'
|
查询结果如下图:
再来看gen_table_column
:
1 2 3 4 5 6 7 8 9
| SELECT COLUMN_NAME, COLUMN_COMMENT, DATA_TYPE FROM information_schema.`COLUMNS` WHERE TABLE_NAME = 'gen_table_column' AND TABLE_SCHEMA = 'ry-vue'
|
执行结果如下:
在Java中,分别按照表gen_table
,gen_table_column
构建两个实体对象,即Entity,以便后续通过mybatis等对其进行保存等相关操作。
我们截图部分源码代码(其所属位置位于若依项目:ruoyi-generator/src/main/java/com/ruoyi/generator/domain路径下):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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 |
对于列名,将其转换为驼峰命名法;对于表名,一是注意需要去掉某些指定前缀,二是将剩余部分转换为首字母大写的驼峰。
对于转换为驼峰的方式,我在若依系统源码中发现有两个不同的实现方式,供大家参考:
第一种,从字符串开头,通过大写标识依次拼接字符:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
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(); }
|
第二种,按照下划线拆分原始字符串后,依次首字母大小,然后拼接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
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,结构信息如下:
经过转换,存储在gen_table
以及gen_table_column
中的数据为:
总结
我们便可不需要通过information_schema
数据库查询信息,而仅需要通过这两个gen_
表数据生成对应的类信息。通过其存储数据,我们也可以看到,表中存储了构建对象属性的类型、名称,这也便于后续直接生成对象,而不需要再次将其转换,减轻了一步操作的系统压力。
通过使用表“缓存”数据结构,的确是十分高明的方法,值得学习!