SQL 将关系数据库表转 Java 对象

最近用 SpringBoot 重构一个 PHP 项目,用 JPA 操作 MySQL 数据库,由于要维持原来的表结构,应用中要把许多表转化为 Java 类。

一般的 ORM 框架可以很方便地把 Java 类映射为关系数据库表,但这里显然是它的逆过程,这个好像没有现成的工具和框架,难道要对着表一个字段一个字段地写?

要知道,数据库有几十张表,每张表都有很多字段,一个个写还真得花不少精力,而且手写还很容易出错。

最好的办法当然是用程序实现自动转换了,这里我们用 SQL 来实现这种转换。

SQL 实现表转 Java

基本思路就是根据表名查询出列名,用 concat 函数拼接修饰符得到 Java 对象属性列表:

1
2
3
4
5
6
7
8
9
10
SELECT concat('public  ', CASE 
WHEN data_type IN ('varchar', 'char', 'text') THEN 'String'
WHEN data_type IN ('int', 'tinyint') THEN 'Integer'
WHEN data_type IN ('bigint') THEN 'Long'
WHEN data_type IN ('datetime') THEN 'Date'
WHEN data_type IN ('bit', 'boolean') THEN 'Boolean'
ELSE '类型不确定'
END, ' ', column_name, ';') AS java
FROM information_schema.columns
WHERE table_name = 'person';

运行结果就是转换好的 Java 对象属性了,直接复制到类中即可。

封装成 MySQL 存储过程

把上面 SQL 语句封装成存储过程,使用的时候更方便:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

-- 以表名为输入参数,输出对应的java对象属性

CREATE PROCEDURE sql2java (
IN t_name char(30)
)
BEGIN
SELECT concat('public ', CASE
WHEN data_type IN ('varchar', 'char', 'text') THEN 'String'
WHEN data_type IN ('int', 'tinyint') THEN 'Integer'
WHEN data_type IN ('bigint') THEN 'Long'
WHEN data_type IN ('datetime') THEN 'Date'
WHEN data_type IN ('bit', 'boolean') THEN 'Boolean'
ELSE '类型不确定'
END, ' ', column_name, ';') AS java
FROM information_schema.columns
WHERE table_name = t_name;
END;

调用 MySQL 存储过程,直接传入表名即可:

1
call sql2java('person');

循环遍历所有表

数据库中有很多张表,如果我们不想一次次输入表名,通过循环遍历可以一次性得到所有结果。

具体做法是先查出数据库所有表名:

1
2
3
SELECT table_name
FROM information_schema.TABLES
WHERE table_schema = 'db_name';

然后把结果集通过游标和 while 循环遍历所有表:

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 打开游标
open cur;

while done do
-- 获取数据
fetch cur into t_name;

-- 直接调用之前的存储过程
call sql2java (t_name);

end while;
-- 关闭游标
close cur;

最后把上面 SQL 语句封装成 sql2java_all 存储过程。

调用存储过程,可一次性输出所有表的 Java 类:

1
call sql2java_all;

此方法除了可以得到 Java 类,稍作修改也可以支持多语言,比如 Python、PHP 的类,C++、Golang 的结构体以及 Protobuf 的 DSL 代码。

本文 SQL 源码

https://github.com/yunTerry/SQL2Java