懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

需求是这样的:因为我们目前的一个老项目是Oracle数据库的,这个库呢,数据库是没有注释的,而且字段名和表名都是大写风格,比如

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

在代码层面的po呢,以前也是没有任何注释的,但是经过这些年,大家慢慢踩坑多了,也给po加上了一些注释了,比如:

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

现状就是这样,再说说目标是:希望把这个库能转成mysql,表名和字段名最好都用下划线分隔每个单词,字段呢,最好能有注释。也就是差不多下面这样:

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

方案分析

最早我尝试的就是hibernate正向工程,建一个空的mysql库,然后配置hibernate的选项为:

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

这样的话呢,就会自动在我们指定的mysql数据库生成表了,不过,有两个瑕疵是:

生成的表,字段和表名都是和PO里一样的驼峰格式;

没有注释。

第一个问题,我这边是通过覆盖hibernate源码的方式解决,将驼峰转换为了下划线;

第二个问题,麻烦一些,因为要做到字段带注释的话,那就得看看哪里能拿到注释。hibernate执行过程中,从PO类里?不可能,编译好的class里,怎么会有注释呢?那就只能从源文件着手了,PO类的源码里,field上是有注释的,那就必须要去解析PO类的java文件,从里面提取出每个PO类中:字段--》注释的对应关系来。

大方向已定,我们开搞!

最后我这里解决这两个问题,是覆盖了三个hibernate的类的源码,大概如下:

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

在继续之前,先说明一下,这个肯定是要修改hibernate源码的,这里只讲讲怎么覆盖某个jar包里的类:

我这里是spring mvc的老项目,最后是部署在tomcat运行,tomcat的WebAppClassloader,负责加载以下两个路径的class:

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

覆盖的原理,就是依赖其查找class的先后顺序来做,比如lib下的某个jar包有:org.hibernate.mapping.Table这个类,正常情况下,都会加载到这个类;但如果我们在classes下放一个同包名同类名的类,那么就会优先加载我们的这个class了。但是假设这个类引用了hibernate的其他类B,不影响,毕竟我们没覆盖类B,所以还是会到lib下查找,最后还是会使用hibernate jar包中的B。

最终源码已经放在了:https://github.com/cctvckl/work_util/tree/master/Hibernate_PositiveEngineer

问题1解决步骤:驼峰格式的建表语句转下划线

知道怎么覆盖了,再说说怎么去找要覆盖哪儿,这个需要一点经验。我这里先还原成没修改时的样子,跑一下项目,发现日志有以下输出:

2019-10-23 13:47:11.819 [main] DEBUG [] org.hibernate.SQL - drop table if exists KPIRECORD 2019-10-23 13:47:11.823 [main] DEBUG [] org.hibernate.SQL - create table KPIRECORD ( kpiRecordId varchar(255) not null, endTime varchar(255), evaluatorId varchar(255), kpiComment varchar(255), kpiDate datetime, kpiValue double precision, roleCode integer, startTime varchar(255), superiors varchar(255), userId varchar(255), primary key (kpiRecordId) ) 2019-10-23 13:47:11.988 [main] INFO [] org.hibernate.tool.hbm2ddl.SchemaExport - HHH000230: Schema export complete

其他不重要,我们看最后一行,里面包含了Schema export complete,这个肯定是代码里的日志,我们拿这个东西,在代码里搜一波(这一步,要求maven是下载了jar包的源码):

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

接下来,我们点进去,因为maven下载了源码的关系,所以再利用idea的findUsage功能,剩下的,就是在觉得比较靠谱的地方打上断点,运行一下,debug一下,大概就知道流程了。

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

找啊找,找到了下面的地方,(org.hibernate.mapping.Table#sqlCreateString)

懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfzpy.html