行业知识
Nacos2.3.2适配Oracle和PostgreSQL
零、参考与准备
本文参考了 Nacos2.2.0版本适配Oracle 和 Nacos2.2.0版本适配PostgreSQL(含GaussDB),请配合使用。
以下更改均基于 Nacos2.3.2release版本。
一、适配Oracle
1、pom文件
com.oracle.database.jdbc ojdbc6 11.2.0.4
nacos-all的pom里添加依赖管理,nacos-config和nacos-naming的pom里添加依赖使用。
1.5、对2.2.0版本适配的修改
参考里那篇csdn文章修改了ExternalDataSourceProperties文件(现已处在nacos-persistence模块),但是里面修改完的函数好像没有用到,所以改不改区别不大。
2、plugin修改
2.1、com/alibaba/nacos/plugin/datasource/constants/DataSourceConstant.java
/* * Copyright 1999-2022 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.alibaba.nacos.plugin.datasource.constants;/** * The data source name. * * @author hyx **/public class DataSourceConstant { public static final String MYSQL = "mysql"; public static final String DERBY = "derby"; public static final String ORACLE = "oracle"; public static final String POSTGRESQL = "postgresql";} 这里添加了两个字段,ORACLE和POSTGRESQL。(2.2.0那篇csdn里ORACLE拼错了。。)
2.2、Mapper修改
具体代码详见github项目。
和参考里那篇CSDN描述的一致,9个类放在 com/alibaba/nacos/plugin/datasource/impl 目录的新建oracle文件夹下。
和以往不同的是:
- 这个版本nacos的mapper参数都变成了 MapperContext context,而返回值都变成了 MapperResult,这导致了和以前不同的是,我们需要从context里面手动取出startRow和pageSize。同时返回的时候手动封装sql语句和参数列表。
- 2.2.0版本的mapper有一些通用的函数被放在了它的父类当中,我们需要对比着父类删去多余的函数(通常是不需要分页的那些函数)。
- 许多oracle的适配mapper类都会写 "rnum >= " + startRow + " and " + pageSize + " >= rnum" 这种语句,但这是非常不正确的。因为查询第一页时,startRow是0,pageSize比如是10。查询第二页时的startRow是10,pageSize还是10,这样第二页就只会有第10行的值了。所以正确的写法可以参考github当中的"rnum >= " + (startRow + 1) + " and " + (pageSize + startRow) + " >= rnum"。
2.3、SPI注册
同参考里的做法修改com.alibaba.nacos.plugin.datasource.mapper.Mapper,注册我们自己的mapper。
3、public命名空间问题
我们做这一步的原因在于nacos的public命名空间的命名空间ID是空字符串,即''。而mapper里面的sql对应着tenant_id = ?。如果oracle数据库里面tenant_id是空字符串,我们搜索tenant_id = ''传入空字符串的话会匹配不到(使用tenant_id is null倒可以匹配,但修改起来太麻烦,需要从上到下都改),因此我们选择在数据库里存public命名空间的tenant_id时存入'null',搜索的时候我们也tenant_id = 'null'。
因此,我们采用2.2.0版本csdn里2.5当中除了添加id的那些操作(原因看后文),即把所有tenant相关的默认值从空字符串换成null字符串,这样存的时候存null字符串,查的时候也查null字符串。
也就是不修改com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java,不修改com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java,不修改com/alibaba/nacos/core/namespace/repository/ExternalNamespacePersistServiceImpl.java。
修改com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java,修改com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java。
需要注意,2.2.0版本修改少了一处,这会导致在nacos面板看所有命名空间情况的时候看到public命名空间的配置数总为0:
修改com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java当中
@Override public int configInfoCount(String tenant) { if (tenant.equals(StringUtils.EMPTY)) tenant = StringUtils.NULL; ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(); context.putWhereParameter(FieldConstant.TENANT_ID, tenant); MapperResult mapperResult = configInfoMapper.configInfoLikeTenantCount(context); Integer result = jt.queryForObject(mapperResult.getSql(), mapperResult.getParamList().toArray(), Integer.class); if (result == null) { throw new IllegalArgumentException("configInfoCount error"); } return result; } 4、resource关键字问题
按链接中文章的2.5.4操作步骤,把所有的resource换成resources,避免oracle当中的resource关键字报错。
5、application.properties配置
如果你要打包后用脚本启动的话在distribution/conf/application.properties下,否则直接启动程序就在console/src/main/resources/application.properties下:
##### Public Config:nacos.plugin.datasource.log.enabled=true### Count of DB:db.num=1##### If use Oracle as datasource:spring.sql.init.platform=oracle### Connect URL of DB:db.url.0=db.user.0=db.password.0=# db.jdbcDriverName=oracle.jdbc.OracleDriverdb.pool.config.driver-class-name=oracle.jdbc.OracleDriverdb.testQuery=select 1 from dual
6、建表
sql文件见github项目。
由于 2.2.0版本的oracle建表sql 没有自增主键这种东西,所以我通过 在线SQL转换工具 手动转换了nacos自带的mysql的sql语句,同时修改了包括加密字段默认非空不加鉴权启动时报错、sql语句中check不正确、true转换成1、resource转换成resources等问题。
7、打包
使用mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U,打出来的在distribution/target下,可以根据官方文档启动。
二、适配PostgreSQL(含GaussDB)
1、pom文件
同oracle
org.postgresql postgresql 42.2.10
2、plugin修改
同oracle,只不过这次的很简单,直接把mysql的mapper文件复制一下,mysql里面LIMIT ?, ?的换成OFFSET ? LIMIT ?即可。最后在com.alibaba.nacos.plugin.datasource.mapper.Mapper下添加相应内容。
3、application.properties配置
##### If use POSTGRESQL as datasource:spring.sql.init.platform=postgresqldb.url.0=db.user.0=db.password.0=db.pool.config.driver-class-name=org.postgresql.Driver
4、建表
基本直接使用的 Nacos2.2.0版本适配PostgreSQL(含GaussDB) 旧版sql建表,修改了加密字段的not null,为了和oracle一致也修改了resource。
5、打包
同上,注意多数据源的application.properties配置。