若依中的代码生成器-数据库篇

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

继上一篇《若依中的代码自动生成器研究-表查询篇》,我们继续来学习若依系统中的代码生成逻辑。

导入表之Sql查询

在菜单栏点击“代码生成”,在右侧栏中点击“导入”按钮,在文章若依中的代码自动生成器研究-表查询篇中,我们已经一直到若依是通过查询数据库的information_schema.tables从而查询到数据库的所有表。

我们下一步的操作是,“勾选my_user表,点击确定”。操作路径示意图以及通过F12调试,查看接口请求,如下图所示。

image.png

所请求的接口是/tool/gen/importTable,我们通过idea检索后台接口,发现其位于ruoyi-generator/com.ruoyi.generator/controller/GenController下,如下图:

image.png

Controller中的代码源码如下:(我们通过调试,补充上各个值的获取数据)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 导入表结构(保存)
*/
@PreAuthorize("@ss.hasPermi('tool:gen:import')")
@Log(title = "代码生成", businessType = BusinessType.IMPORT)
@PostMapping("/importTable")
public AjaxResult importTableSave(String tables)
{
// 通过调试,字符串tables格式为:"my_user,table_name_1,table_name_2...."
String[] tableNames = Convert.toStrArray(tables);
// tableNames: ["my_user", "table_name_1", "table_name_2"]
// 查询表信息
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
// 见下图
genTableService.importGenTable(tableList);
return AjaxResult.success();
}

image.png

我们来研究一下其中查询表的那句sql,通过在xml中搜索,其执行sql为:

1
2
3
4
5
6
7
8
9
10
11
12
SELECT
table_name,
table_comment,
create_time,
update_time
FROM
information_schema. TABLES
WHERE
table_name NOT LIKE 'qrtz_%'
AND table_name NOT LIKE 'gen_%'
AND table_schema = (SELECT DATABASE())
AND table_name IN ('my_user')

通过这个查询将my_user表的基本信息查询出来。

那么genTableService.importGenTable(tableList);这一句又执行了哪些操作呢?我们继续来看。

导入表之导入

同过定位importGenTable,我们查询到他的执行方法,我们补充上调试过程中的参数值

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
36
/**
* 导入表结构
*
* @param tableList 导入表列表
*/
@Override
@Transactional
public void importGenTable(List<GenTable> tableList)
{
// tableList: [{my_user表的信息}]
// admin
String operName = SecurityUtils.getUsername();
try
{
for (GenTable table : tableList)
{
String tableName = table.getTableName(); // tableName: my_user
GenUtils.initTable(table, operName);
int row = genTableMapper.insertGenTable(table);
if (row > 0)
{
// 保存列信息
List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
for (GenTableColumn column : genTableColumns)
{
GenUtils.initColumnField(column, table);
genTableColumnMapper.insertGenTableColumn(column);
}
}
}
}
catch (Exception e)
{
throw new ServiceException("导入失败:" + e.getMessage());
}
}

其中有一个关键的数据结构:GenTable,它位于Domain中,对应数据库中的表gen_table,字段截图如下所示:

image.png

类似的,另外一个表gen_table_column以及其对应的domain域类为GenTableColumn,保存生成数据库表的列信息,其字段结构如下截图:该表通过字段table_id与表gen_table中的某一行关联上。

image.png

那么查询数据库表的列用的什么sql呢?

通过检查,在xml中检索到sql为:

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
36
37
38
SELECT
column_name,
(
CASE
WHEN (
is_nullable = 'no' && column_key != 'PRI'
) THEN
'1'
ELSE
NULL
END
) AS is_required,
(
CASE
WHEN column_key = 'PRI' THEN
'1'
ELSE
'0'
END
) AS is_pk,
ordinal_position AS sort,
column_comment,
(
CASE
WHEN extra = 'auto_increment' THEN
'1'
ELSE
'0'
END
) AS is_increment,
column_type
FROM
information_schema. COLUMNS
WHERE
table_schema = (SELECT DATABASE())
AND table_name = 'my_user'
ORDER BY
ordinal_position

是通过查询information_schema. COLUMNS并约束table_name以及数据库来查询指定表my_user的所有列。

总结

通过导入操作,将my_user转换为了gen_tablegen_table_column中的几行数据,以便后续代码的生成。