使用 Ora2PG 完成Oracle到PostgreSQL迁移后,就需要修改Java应用的代码了,我们使用的是 Spring Boot + Druid + MyBatis,除了常规的函数不同要修改,比较琐碎的就属子查询要有别名和临时表的问题。
这里,重点讲临时表碰到的问题:
1. 使用 Ora2PG 工具后,发现所有的临时表定义都不在目标导出文件里。以前用Oracle,可以把临时表定义好,Oracle会保证数据隔离的。但是这几个临时表都没导出来,应用在测试时报表不存在。但是在PGAdmin和Navicat里执行临时表的定义语句均可成功,也能查询到,但是一跑应用就说表不存在。网上搜了PostgreSQL 临时表才知道机制不同。
2. 于是我就在需要临时表的语句前用 Spring JdbcTemplate 执行建表语句,结果报 “com.alibaba.druid.sql.parser.ParserException: TODO IDENTIFIER” 和 “sql injecion violation” 错误,但是建表语句在 PG 客户端执行都是没问题的。所以我只能换掉 Druid,尝试 C3P0 连接池。
3. 参照 Spring Boot 集成 MyBatis 与 c3p0 写完代码,运行时报 “ClassNotFoundException: org.postgresql.PGDate ” 错误,但是同样的数据库连接参数 Druid 是可以的,后来才发现 Druid和 C3P0 对读取到的属性值处理不同,Druid会处理值左右的空格,而 C3P0 不会,所以要保证参数值左右不要有空格。
4. 临时表的机制在上面给出的参考链接里,该作者讲的比较清楚了。我对此的理解是:
a) 如果数据在一个事务里是一次消费,那么用 on commit drop
b) 如果同一用户会话里,不同事务间依赖相同表结构,但是产生的数据均不同,用 on commit delete rows
c) 如果类似缓存功能,整个会话期间多个事务都去查询,则用 on commit preserve rows
第一种直接在事务里需要地方创建临时表,后两种都是可以在用户登录的时候或者合适的地方预先创建