猿创征文|从mysql 到kingbase(人大金仓)

article/2025/5/2 6:29:18

一、背景介绍

公司主要做toG 的项目,经常服务于各个地方政府。之前某省会城市下属区县项目,需要将已交付的项目中所使用到的各类中间件全部替换为国产,其中就包括了数据库的替换。项目中一直使用的是mysql数据库,后经商务调研及选型,决定替换为国产数据库 kingBase (人大金仓数据库),并由我负责所有应用的代码迁移工作。

我们的项目采用的是springCloud微服务体系,数据访问层用的是mybatisPlus, 微服务的个数比较多,我需要一个一个迁移并验证,这其实确实是一个比较繁琐且漫长的工作,并且由于只搭建了一套环境的数据库,我没法本地连接调试,每次都只能发包后通过观察错误日志的方式进行排查,给我的迁移工作增加了更大的困难。

二、适配过程

这里先强调一下,我的主要工作是把当前使用的mysql数据库,切换到人大金仓数据库上,这是一个迁移的过程,而不是说一个新项目从头开始就使用人大金仓,所以我所关注的主要就是mysql和人大金仓的兼容性上,把一些人大金仓无法成功的执行的mysql 中的语句改成能让他执行的语句。

而适配的第一步,其实主要是人大金仓的技术人员和我方的运维人员的工作。 首先由人大金仓的技术人员在我方指定的服务器上,帮助我们安装人大金仓的数据库,并且提供人大金仓(下面都使用kingbase替代)的数据库连接工具和相关的技术文档。并由我方运维人员根据他们提供的数据库迁移手册,将mysql上的数据迁移到kingbase中。完成迁移后,会给我一个kingbase数据库的连接相关信息(url,username,password等)和一份迁移文档。

接下来我就要根据文档进行应用上数据库迁移了,这里所说的迁移,其实就是做一个替换,将代码里的mysql连接替换成kingbase连接。替换步骤如下:

  1. 更换驱动

    对方技术人员提供了一个驱动jar包,kingbase8-x.x.x.jar ,首先第一步我先将这个jar包上传到了公司私服上,然后用坐标的方式将其配置到了项目的pom文件中,同时注释掉里面的mysql驱动。

  2. 修改数据库连接配置信息

    由于我们使用的是nacos配置中心,直接在nacos里进行修改:

spring:datasource:driver-class-name: com.kingbase8.Driver # 配置MySQL8的驱动程序类url: jdbc:kingbase8:/host:port/database?para1=val1...username: root # 数据库用户名password: root # 数据库连接密码

      3. 重新启动服务,测试,解决报错。

上面这几步就是迁移的主要步骤了,如果运气比较好,完成上面的改动后,服务应该会正常启动,但是也有可能会出现一些问题,接下来就是要具体问题具体分析了,报的错误基本上都是sql不兼容的一些问题。然后就要根据具体的报错情况进行sql的适配。同时人大金仓的技术人员也会组建一个答疑的群,遇到一些报错可以发到答疑群中,他们也会有专业的技术人员进行解答。

三、常见问题解决

问题一: Error updateting database. Cause: com.kingbase8.util.KSQLException: ERROR: syntax error at or near "`"

这个问题是由于kingbase数据库不支持反引号造成的,有一些框架在生成一些增删改查语句的时候,可能习惯将字段名称使用反引号包裹起来,我们需要将反引号去掉或者改为双引号引号重新启动项目后解决。

类似于:

问题二: DATE_ADD函数不支持

sql中有使用DATE_ADD函数的地方报错,原因是默认的kingbase中是没有DATE_ADD函数的,需要自己创建(非系统函数,每个库都需要创建): 创建代码如下:

create or replace function date_add(v_date text , v_interval interval)returns text as $$declarev_rt text;beginselect to_char(v_date::timestamp(0) + v_interval,'yyyy-mm-dd hh24:mi:ss' ) into v_rt;if length(v_date) = 10 and v_rt like '% 00:00:00' thenselect substr(v_rt,0,10) into v_rt;end if;return v_rt;end;$$LANGUAGE plpgsql;

问题三: DATE_FORMAT 函数不支持

解决方案: 需要自己创建(非系统函数,每个库都需要创建),创建语句如下:

create or replace function date_format(para1 timestamp,para2 text) returns text
as $$
declare
form1 text;
begin
--form1=replace(para2,'%M','Month');
form1=replace(para2,'%W','Day');
--form1=replace(form1,'%D','DDth');
form1=replace(form1,'%Y','YYYY');
--form1=replace(form1,'%y','yy');
form1=replace(form1,'%a','Dy');
form1=replace(form1,'%d','DD');
form1=replace(form1,'%e','DD');
form1=replace(form1,'%m','MM');
form1=replace(form1,'%c','MM');
form1=replace(form1,'%b','Mon');
form1=replace(form1,'%j','DDD');
form1=replace(form1,'%H','HH24');
form1=replace(form1,'%k','HH24');
--form1=replace(form1,'%h','HH');
--form1=replace(form1,'%I','HH');
form1=replace(form1,'%l','HH');
form1=replace(form1,'%i','MI');
form1=replace(form1,'%r','HH:MI:SS');
form1=replace(form1,'%T','HH24:MI:SS');
--form1=replace(form1,'%S','SS');
form1=replace(form1,'%s','SS');
form1=replace(form1,'%%','%');
return to_char(para1,form1);
end;
$$ LANGUAGE plpgsql;

问题四: Cause: com.github.pagehelper.PageException: 无法自动获取数据库类型,请通过 helperDialect 参数指定!

解决方案: 在配置文件中手动指定:

pagehelper:helperDialect: postgresqlauto-runtime-dialect: false #默认参数,由于我的项目本地写死了true,我这里需要强制覆盖一下,如果配置成true,上面的配置不生效

问题五: ORDER BY isnull(kpi_seq), kpi_seq ASC ,create_time desc 报错

解决方案: kingbase不支持 isnull(字段名)的写法,需要改为一下写法:

ORDER BY kpi_seq isnull, kpi_seq ASC ,create_time desc

问题六: ERROR: CONNECT BY clause required in this query block

解决方案: 这个问题,主要是我在sql中使用了类似于name, level这样的关键字,kingbase中对于关键字的要求还是比较多的,有一些关键字是不允许我们在sql中使用的。解决方案有两种,一是把这些关键字的字段名修改一下。二是设置关键字的忽略。具体关键字有哪些,可以参考kingbase提供的文档,里面有详细参数。关键字忽略的方式,执行如下sql:

alter system set exclude_reserved_words = 'level';
select sys_reload_conf();

问题七: druid连接池在连接kingbase时会产生dbType not support, 或者 无法识别数据库类型的错误。

解决方案: 由于druild中一般会自动根据jdbc-url自动检查数据库的类型,但是它里面只有检查url中是否包含kingbase, 但是却不认识kingbase8,就会出现这个问题,我们需要自己设置driverClassName,同时druild的filter中要把wall去掉,因为kingbase不支持这个参数。

druidDataSource.setFilters("stat,slf4j");
druidDataSource.setDriverClassName("com.kingbase8.Driver")

问题八: com.kingbase8.util.KSQLException: Cannot convert the column of type TINYINT to requested type boolean.

解决方案: 这个问题主要是由于mysql中没有boolean类型,所以一般都使用tinyint来存储标志位,然后在实体中使用boolean类型来接收,类似mybatis或者mybatisPlus框架都会自动把tinyint类型转换为boolean类型。但是在kingbase里就不行了,解决方案: 这里只针对mybatisPlus,

首先实体类上的TableName注解中加入一个 autoResultMap = true

@TableName(value = “d_lc_res”, autoResultMap = true)

然后在boolean类型的字段注解上加上一个TypeHandler

@TableField(typeHandler = TinyIntToBooleanHandler.class, jdbcType= JdbcType.TINYINT)
private Boolean warningFlag;

TinyIntToBooleanHandler:

package com.xxx.global.config.mp;import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/**
* @className: TinyIntToBooleanHandler
* @description: 
* @author liushuai
* @date 2022/9/19 3:21 PM
*/
@MappedTypes({Boolean.class})
@MappedJdbcTypes({JdbcType.TINYINT})
public class TinyIntToBooleanHandler extends BaseTypeHandler<Boolean> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {ps.setInt(i,Boolean.TRUE.equals(parameter) ? 1 : 0 );}@Overridepublic Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {int anInt = rs.getInt(columnName);return Integer.valueOf("1").equals(anInt);}@Overridepublic Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException {int anInt = rs.getInt(columnIndex);return Integer.valueOf("1").equals(anInt);}@Overridepublic Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {int anInt = cs.getInt(columnIndex);return Integer.valueOf("1").equals(anInt);}
}

这样就可以了,这里要注意,这种方式只对mybatis已经封装好的方法有效,比如list, getOne,等,如果是我们自己写的sql, 还需要做进一步的处理:

对于自己写的sql, 我们需要使用resultMap来接收, 同时在定义resultMap的时候,给相应字段添加typeHandler属性:

<resultMap id="kpiDO" type="com.xxx.entity.KpiDO"><result column="warningFlag" property="warningFlag" typeHandler="com.cestc.global.config.mp.TinyIntToBooleanHandler" />// 省略其他字段</resultMap>

四、总结

上面就是最近一段时间在迁移国产数据库过程中的一些步骤和解决问题的方式,希望能够给大家带来帮助。整体来说迁移的过程还是比较痛苦的,上面只列出了常规应用的一些问题,还有一些使用动态数据源的应用,迁移起来的问题其实更大,像一些查询所有库,查询所有表,查询所有字段的sql写法和mysql都是完全不一样的。

虽然过程很艰辛,但是我想说的是,在大形势不断紧张的情况下,还是支持有更多企业、机构甚至个人,可以更多的支持国产软件的发展,有朝一日让我们的国产软件也能够站在世界的顶端,我们软件人不在遭受其他人的制裁与威胁。希望这一天早日到来,这也是全体中国软件人真正站起来的时候。


http://chatgpt.dhexx.cn/article/HyR9Wwjs.shtml

相关文章

如何评价唐卫国公李靖的战功、军事才能、政治才能?

link 一鞭直渡清河洛 Research and no development 已关注 470 人赞同了该回答 个人以为&#xff0c;在军事上&#xff0c;李靖是当之无愧的唐朝第一名将&#xff0c;他用兵如神&#xff0c;精于谋略&#xff0c;无论是在实际的军事指挥上&#xff0c;还是军事理论上&#xff0…

PHP汉字取拼音缩写

<?php class ChineseSpell { /** * var array $chineseSpellList 拼音编码对应表 * access private */ private $chineseSpellList array( a>-20319, ai>-20317, an>-20304, ang>-20295, ao>-20292, ba>-20283, bai>-20265, ban>-20257, bang>…

js获取汉字拼音首字母

使用pinyin-pro这个npm包 github: https://github.com/zh-lx/pinyin-pro 特色功能 支持汉字、词语、句子多种格式输入获取获取拼音获取声母获取韵母获取拼音首字母获取音调获取多音字的多种拼音支持字符串和数组两种输出形式 版本更新 当前版本&#xff1a; 3.0.7 -> 3.…

Oracle 获取汉字拼音首字母

Oracle 获取汉字拼音首字母 获取汉字拼音函数脚本 CREATE OR REPLACE FUNCTION F_GETPY(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS V_COMPARE VARCHAR2(100); V_RETURN VARCHAR2(4000);FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN NLSSORT(P_WOR…

java获取中文拼音首字母

import net.sourceforge.pinyin4j.PinyinHelper;public class PinyinHelperUtil {/*** 返回中文的首字母** param str* return*/public static String getPinYinHeadChar(String str) {String convert "";for (int j 0; j < str.length(); j) {char word str.c…

java获取中文字符串汉语拼音和首字母

业务需求&#xff1a;将用户中文名字根据拼音首字母分类排序 直接上代码&#xff1a; 引入依赖&#xff1a; <dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.0</version></depend…

excel中提取中文拼音

概述&#xff1a;在工作时&#xff0c;有时候会用到汉语拼音&#xff0c;本文讲述如何在Excel中通过vba程序提取汉字的拼音。 1、altF11调出vba编写窗口 2、新建——模块 3、粘贴以下代码 Function PinYin2(Hz As String)Dim PinMa As StringDim MyPinMa As VariantDim Temp As…

MYSQL 中取拼音首字母的函数

2019独角兽企业重金招聘Python工程师标准>>> 今天碰到了取拼音首字母的需求。整理了一下。 1、编码表&#xff1a; /*DDL Information For - test.cs_char2letter*/ ------------------------------------------------------ Table Create Table …

Openlayers利用kriging.js实现纯前端插值

关于空间插值这一块&#xff0c;也是GIS一个重要的分析。前端可以通过turf.js后端可以采用contour&#xff0c;如果仅有少量数据需要进行插值分析并进行展示&#xff0c;那应当如何做&#xff1f;可以采用turf.js但是turf.js插值效果是真的烂。通过检索发现可以通过kriging.js去…

Cesium+kriging.js实现雨量插值

0.前言 网上有很多关于openlayers的克里金插值&#xff0c;但是最近在学习cesium&#xff0c;也想在cesium中做&#xff0c;但是好像网上相关的例子一个都没有。所以我就自己尝试去做。 1.克里金插值 克里金插值也称作空间局部插值法&#xff0c;或空间自协方差最佳插值法&…

色斑图制作及后端无人值守自动出图kriging.js+chrome+html2canvas.js+DOS+BIGEMAP超低成本实现气象要素色斑图

目录 一、问题由来 二、探索 三、尝试 四、修正 五、优化方案 六、kriging.js 使用感受小结 七、参考文章 八、原始例程下载 下载连接&#xff1a;https://download.csdn.net/download/jessezappy/16769114 一、问题由来 因业务需要&#xff0c;需要根据小时温度、雨量…

基于 Python(gma) 的 克里金(Kriging)法插值的主要过程

由于克里金插值的复杂性&#xff0c;本文不再对其原理进行介绍。详情可自行百度。 本算法基于 Python 的开源克里金插值包 pykrige。但本算法已对其进行改造&#xff0c;以使其符合 gma 的整体逻辑。本算法已不包含任何 pykrige 的原始代码。 原始代码构建 from gma.algorithm…

AAAI2021论文: 时空Kriging的归纳式图神经网络

1、文章信息 《Inductive Graph Neural Networks for Spatiotemporal Kriging》。麦吉尔大学发表在AAAI 2021上的一篇文章。 原文和代码链接&#xff1a; https://github.com/Kaimaoge/IGNNK 2、摘要 时间序列预测和时空Kriging是时空数据分析中最重要的两项任务。近年来&#…

Cesium结合kriging.js制作降雨等值面

Cesium结合kriging.js制作降雨等值面 前因实现效果图使用克里金插值kriging.js使用方法解析 前因 因工作需要使用cesium制作降雨等值面&#xff0c;所以在参考众多博客后。终于是成功实现了降雨等值面。 参考博客&#xff1a; https://blog.csdn.net/weixin_44265800/article/…

kriging及其加点准则学习

什么是加点&#xff1f; 所谓加点&#xff0c;就是给数据集增添数据点对模型进行训练。添加数据点&#xff0c;意思就是获得这个想要的数据点的真实响应&#xff0c;可以是实验的结果&#xff0c;也可以精细仿真的结果。但不管怎样&#xff0c;每增加一个数据点&#xff0c;都…

openlayers加kriging出等值线图

openlayers加kriging出等值线图 方法一 效果图 代码 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><title>前端空间插值</title><style>html, body, #map {height: 100%;width: 100%;}</style><link…

leflet使用kriging.js构建气象图层

一、克里金法 kriging.js kriging.js是一个 Javascript 库&#xff0c;通过普通克里金算法提供空间预测和映射功能。 克里金法是一种高斯过程&#xff0c;其中使用核回归将二维坐标映射到某个目标变量。该算法经过专门设计&#xff0c;可通过为变异函数参数分配先验参数来准确…

Kriging(克里金模型)介绍

克里金模型最早出现在地质学文献中&#xff0c;用来估计有价值矿物的分布。萨克斯艾尔1989年将这种方法应用于近似的计算机实验。此后&#xff0c;克里格法被广泛研究并应用于工程领域。 克里格模型也称为高斯过程模型&#xff0c;因为它将目标函数建模为高斯过程的实现。定义…

克里金(kriging)模型的推导详解

Kriging模型理论推导 1、前言2、条件3、基础知识3.1、方差的理解3.2、概率密度函数3.3、多元正态分布 4、理论推导4.1 模型建立4.2 模型预测 1、前言 简介&#xff1a;Kriging模型是一种通过已知试验点信息来预测未知试验点上响应的无偏估计模型&#xff0c;其最早是由南非矿业…

c语言函数库----<ctype.h>

<ctype.h>是c标准函数库中的头文件&#xff0c;定义了一批c语言字符分类函数&#xff0c;下面将介绍<ctype.h>中的一些函数。 1、isascii()函数 isascii()函数是c语言中字符检测函数。通常用于检查参数c是否为ASCII 码字符&#xff0c;也就是判断c 的范围是否在0…