MySQL迁移到高斯数据库

2023/09/04

1. 前言

公司要求项目去适配高斯数据库,看了一下,高斯数据库就可以当做postgresql用,有啥问题把高斯换成postgresql来查就行。
其实整个项目没有太大的变动,只是几个函数需要改一下,如果用mybatis就更简单了:

@Bean public VendorDatabaseIdProvider vendorDatabaseIdProvider() { VendorDatabaseIdProvider vendorDatabaseIdProvider = new VendorDatabaseIdProvider(); Properties properties = new Properties(); properties.put("MySQL", "mysql"); properties.put("Oracle", "oracle"); properties.put("PostgreSQL", "pgsql"); properties.put("DM DBMS", "dm"); vendorDatabaseIdProvider.setProperties(properties); return vendorDatabaseIdProvider; } @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("dataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); factoryBean.setDatabaseIdProvider(databaseIdProvider()); factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); return factoryBean; }
java

添加上面配置后,碰到不兼容的函数可以这样处理:

<select id="maxid" databaseId="pgsql" resultType="int"> select another_max(power_id) from tb_xx </select> <!-- 给一个默认的 --> <select id="maxid" resultType="int"> select max(power_id) from tb_xx </select>
xml

这样idea会爆红,可能看着有点不舒服。

也可以考虑这样写:

<choose> <when test="_databaseId == 'oracle'"> xxx </when> <when test="_databaseId == 'dm'"> xxx </when> <when test="_databaseId == 'mysql'"> xxx </when> <when test="_databaseId == 'informix' or _databaseId == 'gbase8s'"> xxx </when> <otherwise> xxx </otherwise> </choose>
xml

两种都可以,如果太复杂了建议用第一种。


本来到这,已经完事大吉了,就去mapper里面去检查一下有没有哪个函数是高斯没有的,然后改一下就行。

结果,万万没想到,项目里面有拿StringBuilder搞SQL拼串的代码,结果写的全是坑,这玩意狠狠折磨了我好几个星期!

2. 别名问题

SELECT id AS userId FROM user
sql

上面这个SQL很简单,就是查用户id,然后起个别名叫userId,乍一看好像没什么,下面我放个图,大家来找不同:

找不同

发现了吗?仔细看一下userId,有没有发现查出来全部变成小写了?

在我们项目代码里,直接从结果集里面拿userId,结果拿不到爆空指针!

原本我以为是配置问题,把大小写搞得不敏感了,结果去网上搜了一下,结果只有表名能修改大小写敏感。

所以要怎么改呢,其实只需要在别名的左右加上双引号就行了:

SELECT id AS "userId" FROM user
sql

这个操作同样兼容mysql。

3. COUNT(*)

SELECT COUNT(*) FROM userId
sql

又是一个非常简单的SQL,然后咱们又来找不同:

高斯的结果:

gs-count

mysql的结果:

mysql-count

相信一眼就能看出来,mysql拿需要用COUNT(*),而高斯则需要用count拿。

这里最好的解决办法就只有取别名了,全部都叫同一个就行了。

不兼容的函数/语法

MySql函数名高斯函数名说明
LIMIT offset, sizeLIMIT size OFFSET offset高斯不支持mysql的语法,Mysql支持高斯的语法,更换时注意offset和size的位置需要交换
group_concat(col)array_to_string(array_agg(col), ',')group_concat
date_format(col, '%Y-%m-%d')to_char(col, 'yyyy-mm-dd')日期转字符串
delete from tb1, tb2不兼容,推荐使用子查询mysql 删除时选择两张表,高斯不支持
IFNULL(xx, fallback)COALESCE(xx, fallback)当列为空时使用默认值