最近用SpringBoot重構一個PHP項目,用JPA操作MySQL數據庫,由于要維持原來的表結構,應用中就要把許多表轉化為Java類。
一般的ORM框架可以很方便地把Java類映射為關系數據庫表,但這里顯然是它的逆過程,這個好像沒有現成的工具和框架,難道要對著表一個字段一個字段地寫?
要知道,數據庫有幾十張表,每張表都有很多字段,一個個寫還真得花不少精力,而且手寫還很容易出錯。
最好的辦法當然是用程序實現自動轉換了,這里我們用SQL來實現這種轉換。
SQL實現表轉Java
基本思路就是根據表名查詢出列名,用concat函數拼接修飾符得到Java對象屬性列表:
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語句封裝成存儲過程,使用的時候更方便:
-- 以表名為輸入參數,輸出對應的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 存儲過程,直接傳入表名即可:
call sql2java('person');
循環遍歷所有表
數據庫中有很多張表,如果我們不想一次次輸入表名,通過循環遍歷可以一次性得到所有結果。
具體做法是先查出數據庫所有表名:
SELECT
table_name
FROM
information_schema. TABLES
WHERE
table_schema = 'db_name';
然后把結果集通過游標和while循環遍歷所有表:
-- 打開游標
open cur;
while done do
-- 獲取數據
fetch cur into t_name;
-- 直接調用之前的存儲過程
call sql2java (t_name);
end
while;
-- 關閉游標
close cur;
最后把上面SQL語句封裝成 sql2java_all 存儲過程。
調用存儲過程,可一次性輸出所有表的Java類:
call sql2java_all;
此方法除了可以得到Java類,稍作修改也可以支持多語言,比如Python、PHP的類,C++、Golang 的結構體以及Protobuf 的DSL代碼。