springboot项目中,MySQL数据库转达梦数据库

前言

前段时间,公司要求要把某几个项目的数据库换成达梦数据库,说是为了国产化。我就挺无语的,三四年的项目了,现在说要换数据库。我一开始以为这个达梦数据库应该是和TIDB差不多的。

我之前做的好几个项目部署到测试服、正式服就是用的TIDB,因为它几乎完全兼容MySQL,我本地都甚至没有安装,打包到测试服有极少数不兼容的写法也是临时改的。

然后我去查了下资料,按照教程安装了达梦,并且使用它自带的迁移工具,将数据库迁移到了达梦;再将项目的pom、yml文件也改了之后,运行,好,正常启动了,于是点页面,我直接傻眼,全报错。点一个页面就报错。全是语法问题,无效的列名、无效的函数这些。

我直接:

在这里插入图片描述

好好好,这么玩是吧,我怒改SQL,然后发现不管是查询,还是新增、修改、删除,只要是原生SQL,绝大多数都要改。

在这里插入图片描述

这个时候就完美体现了mybatis-plus的好处了,用的它自带的增删改查,就完全不用改,除非是查询用到了QueryWrapper的apply方法构建了sql,sql里面有达梦不支持的写法或函数,才需要改。

那我没有办法,项目很多都是联表查询、子查询、分组统计,写了很多原生SQL;新增和修改也是,很多地方用到 on DUPLICATE key ,也全部要改掉。

所以这篇文章来说一下我改SQL的过程中,遇到的一些不兼容的写法,应该如何改正。

转移

首先要先去下载安装达梦数据库,安装完了后,可以使用那个工具自带的数据迁移工具,将MySQL迁移至达梦。

下载的时候,记得下载最新版,我自己下载的是2024.4月份的版本,新版对mysql的兼容性最好,能最小程度地改动sql。当然如果公司要求用某个旧版本,那就没办法了。我就是,我本地用的新版,其实没有花太多时间改,都是抽空改的,边改边研究,不知道达梦对应的写法或函数就问AI,花了不到两天时间就改完了,全部可以正常运行。但是!!!我打包发给别人部署的时候,全是报错,我人都傻了,晚上我人都在家躺着了,都被叫回去加班了😭后面在我的追问下,才告诉我正式服用的版本是2021.9月份的版本。。。问能不能升级,说不能,甲方要求要用这个版本。。。

迁移完之后,打开DM管理工具,新建连接,用户名密码默认是 SYSDBA,连接进来后,点开模式,就可以找到之前迁移的数据库了。(在达梦,模式就是对应MySQL的数据库)

不过好像说直接用迁移工具迁移会丢失数据,就是有些不兼容的地方。。。

还有个注意的地方,就是你迁移好了,把这个模式导出成 dmp文件,需要注意你这个模式有没有设置 模式拥有者,如果设置了,那么在另一个地方给同样的模式导入的这份数据的时候,也需要给另一个地方的模式设置同样的模式拥有者

比如,模式名叫 DEMO,你设置了它的拥有者 TEST,之后导出这个模式,得到了一个dmp文件。然后你在另一台电脑上,想要导入这份dmp数据,就需要建一个同名模式 DEMO,同样设置拥有者为 TEST,这样再去导入那份dmp文件,才可以。(模式拥有者 可以在用户——>管理用户 这里右键,新建用户,这里的用户就可以设置成 模式拥有者

除了导出成dmp文件,也可以导出成sql文件,

将数据迁移到达梦后,就可以在项目中,开始改代码,换成达梦了。

改SQL

group by

在mysql中,使用了group by,假如要查询非分组的字段,除了用max()、min()之外,像如果是字符串类型,我一般会用 any_value(),达梦没有这个函数,我就直接改成用max()或min()了,这是最快的方法。

还有一个旧版本需要注意的问题:假如你的select中,需要对某个字段a进行计算或者其它处理,最后的结果被命名为了b,但是在表中并不存在b这个字段,然后对b进行 group by,代码如下:

# result在 sys_user 表中并不存在
SELECT DATE_FORMAT(create_time,'%Y-%m-%d') result
FROM sys_user
GROUP BY result

在旧版本达梦中(具体多旧不知道,反正2021.9这个版本是不支持的),这样的写法不支持,会报无效的列名 result。要想在改动最小的情况下正确执行这段代码,需要再包一层:

SELECT result
FROM(SELECT DATE_FORMAT(create_time,'%Y-%m-%d') resultFROM sys_user
) a
GROUP BY result

关于true和false

在旧版本中,直接使用 true 和 false 作为字面量在是不被识别的,因为它期望的是具体的数值或字符串值。

所以if(state > 1,true,false) 或者 CASE WHEN state > 1 THEN true ELSE false END 都会报错。需要将true、false换成具体的数值或字符串才可。

日期格式化、日期加减运算

MySQL中,日期格式化,一般是用 DATE_FORMAT 函数,然后在达梦中,对应 DATE_FORMAT 函数的用法是 TO_CHAR(date,'YYYY-MM-DD') ,格式化的format写法也和mysql的format写法不太一样,这个需要注意。

第二个就是日期时间处理计算,经常会用到的加减时间运算。

MySQL的用法:

# 减运算
DATE_SUB(date,INTERVAL expr unit)
# 加运算
DATE_ADD(date,INTERVAL expr unit)

达梦的用法:

# 减运算
date - INTERVAL expr unit
# 加运算
date + INTERVAL expr unit

多的请看:达梦技术文档-日期运算

on DUPLICATE key 的替换方案

MySQL中,on DUPLICATE key UPDATE 的使用还是挺频繁的,那么在达梦中应该怎么实现一样功能效果呢?

假设我是根据唯一约束索引 user_name 来判断新增或更新的(用主键id也可以)

MySQL中,我有下面一段SQL

<insert id="insertOrUpdateBatch"><foreach collection ="list" item="item" separator =";">INSERT INTO sys_user<trim prefix="(" suffix=")" suffixOverrides=","><if test="null != item.id and '' != item.id">id,</if><if test="null != item.userName and '' != item.userName">user_name,</if><if test="null != item.realName and '' != item.realName">real_name,</if><if test="null != item.deptId and '' != item.deptId">dept_id,</if><if test="null != item.roleId and '' != item.roleId">role_id,</if><if test="null != item.password and '' != item.password">password,</if></trim>VALUES<trim prefix="(" suffix=")" suffixOverrides=","><if test="null != item.id and '' != item.id">#{item.id},</if><if test="null != item.userName and '' != item.userName">#{item.userName},</if><if test="null != item.realName and '' != item.realName">#{item.realName},</if><if test="null != item.deptId and '' != item.deptId">#{item.deptId},</if><if test="null != item.roleId and '' != item.roleId">#{item.roleId},</if><if test="null != item.password and '' != item.password">#{item.password},</if></trim><!-- 根据唯一约束 user_name 来更新下面几个字段的值 -->on DUPLICATE key UPDATE<trim suffixOverrides=","><if test="null != item.realName and '' != item.realName">real_name = #{item.realName},</if><if test="null != item.deptId and '' != item.deptId">dept_id = #{item.deptId},</if><if test="null != item.roleId and '' != item.roleId">role_id = #{item.roleId},</if><if test="null != item.password and '' != item.password">password = #{item.password},</if></trim></foreach>
</insert>

或者是:

INSERT INTO sys_user (id,user_name,real_name ,dept_id ,role_id,password)
VALUES
<foreach collection ="list" item="item" separator =",">(#{item.id},#{item.userName},#{item.realName},#{item.deptI},#{item.roleId},#{item.password})
</foreach>
on DUPLICATE key UPDATE real_name = values(real_name),dept_id = values(dept_id),role_id = values(role_id),password = values(password)

那么在达梦中,就改成这样的写法:

MERGE INTO sys_user T1
USING (<foreach collection="list" item="item" index="index" separator="UNION ALL">SELECT  #{item.id} id,#{item.userName} user_name,#{item.realName} real_name,#{item.deptId} dept_id,#{item.roleId} role_id,#{item.password} passwordFROM dual</foreach>
) T2 ON (T1.user_name = T2.user_name) <!-- 根据唯一约束 user_name 来更新 -->
# ) T2 ON (T1.id = T2.id) <!-- 这里就是根据主键 id 来更新 -->
WHEN NOT MATCHED THEN INSERT(id, user_name, real_name,dept_id,role_id,password)
VALUES (T2.id, T2.user_name, T2.real_name, T2.dept_id, T2.role_id, T2.password)
<!-- 更新这几个字段的值 -->
WHEN MATCHED THEN UPDATE SET T1.real_name = T2.real_name,T1.dept_id = T2.dept_id,T1.role_id = T2.role_id,T1.password = T2.password

FIND_IN_SET

FIND_IN_SET函数,也是经常使用的一个函数,我去找了下,在22年4季度的版本以后,达梦才支持这个函数的,之前的版本都不支持。

然后我去找了下有没有替代方案,发现无一例外都是叫你自己建一个FIND_IN_SET函数。。。自己建,那我还是选择把FIND_IN_SET改成IN吧,不支持这个,IN总支持吧。所以改成 IN 就是我的解决方案。

关于MySQL的符号 `

MySQL中,一般如果字段是关键字,会推荐加上符号 ` ,还有使用表名也有的时候可能会有这个符号,像这样:

select `name`,`password`
from `sys_user`

然后要注意,达梦不管是新版本还是旧版本,都没有这个符号,不支持这么写,所以改的时候看到这个符号记得去掉。

关于达梦的管理工具

改sql一般我会把sql复制到达梦的管理工具里,执行一下,看看能不能执行成功。然后那些sql语句,指定表名时,需要在前面加上模式名,如下:

select *
from DEMO.SYS_USER

不想加模式名的话,解决方法看这里:达梦数据库,写 SQL 如何才能不带上模式名?

第二个需要注意的就是,用管理工具,执行增删改语句时,执行完了需要提交事务才会生效。不然你会像我一样,搞半天都想不明白为什么语句都执行成功了,却没有生效。

还有就是浏览表数据的时候,你改了表数据,也需要先保存才算是更改成功了。

最后

(这是一篇去年写的文章了,当时一直忘了没发出来。)

更多的语法和函数用法,请参考:达梦技术文档-SQL开发指南

如果还是有疑问的话,可以去问答区找找:达梦技术社区-问答区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/77706.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Quest开发】透视环境下抠出身体并能遮挡身体上的服装

软件&#xff1a;Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72 硬件&#xff1a;Meta Quest3 仅针对urp管线 博主搞这个主要是想做现实里的人的变身功能&#xff0c;最后效果如下 可以看到虽然身体是半透明的&#xff0c;但是裙子依旧被完全遮挡了 原理是参考…

前端安全中的XSS(跨站脚本攻击)

XSS 类型 存储型 XSS 特征&#xff1a;恶意脚本存储在服务器&#xff08;如数据库&#xff09;&#xff0c;用户访问受感染页面时触发。场景&#xff1a;用户评论、论坛帖子等持久化内容。影响范围&#xff1a;所有访问该页面的用户。 反射型 XSS 特征&#xff1a;恶意脚本通过…

(第三篇)Springcloud之Ribbon负载均衡

一、简介 1、介绍 Spring Cloud Ribbon是Netflix发布的开源项目&#xff0c;是基于Netflix Ribbon实现的一套客户端负载均衡的工具。主要功能是提供客户端的软件负载均衡算法&#xff0c;将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时&…

大模型——使用coze搭建基于DeepSeek大模型的智能体实现智能客服问答

大模型——使用coze搭建基于DeepSeek大模型的智能体实现智能客服问答 本章实验完全依托于coze在线平台,不需要本地部署任何应用。 实验介绍 1.coze介绍 扣子(coze)是新一代 AI 应用开发平台。无论你是否有编程基础,都可以在扣子上快速搭建基于大模型的各类 AI 应用,并…

【计算机视觉】目标检测:深度解析YOLOv9:下一代实时目标检测架构的创新与实战

深度解析YOLOv9&#xff1a;下一代实时目标检测架构的创新与实战 架构演进与技术创新YOLOv9的设计哲学核心创新解析1. 可编程梯度信息&#xff08;PGI&#xff09;2. 广义高效层聚合网络&#xff08;GELAN&#xff09;3. 轻量级设计 环境配置与快速开始硬件需求建议详细安装步骤…

【SpringBoot】基于MybatisPlus的博客管理系统(1)

1.准备工作 1.1数据库 -- 建表SQL create database if not exists java_blog_spring charset utf8mb4;use java_blog_spring; -- 用户表 DROP TABLE IF EXISTS java_blog_spring.user_info; CREATE TABLE java_blog_spring.user_info(id INT NOT NULL AUTO_INCREMENT,user_na…

贵族运动项目有哪些·棒球1号位

10个具有代表性的贵族运动&#xff1a; 高尔夫 马术 网球 帆船 击剑 斯诺克 冰球 私人飞机驾驶 深海潜水 马球 贵族运动通常指具有较高参与成本、历史底蕴或社交属性的运动&#xff0c;而棒球作为一项大众化团队运动&#xff0c;与典型贵族运动的结合较为罕见。从以下几个角度探…

【Tauri2】035——sql和sqlx

前言 这篇就来看看插件sql SQL | Taurihttps://tauri.app/plugin/sql/ 正文 准备 添加依赖 tauri-plugin-sql {version "2.2.0",features ["sqlite"]} features可以是mysql、sqlite、postsql 进去features看看 sqlite ["sqlx/sqlite&quo…

全链路自动化AIGC内容工厂:构建企业级智能内容生产系统

一、工业化AIGC系统架构 1.1 生产流程设计 [需求输入] → [创意生成] → [多模态生产] → [质量审核] → [多平台分发] ↑ ↓ ↑ [用户反馈] ← [效果分析] ← [数据埋点] ← [内容投放] 1.2 技术指标要求 指标 标准值 实现方案 单日产能 1,000,000 分布式推理集群 内容合规率…

是否想要一个桌面哆啦A梦的宠物

是否想拥有一个在指定时间喊你的桌面宠物呢&#xff08;手动狗头&#xff09; 如果你有更好的想法&#xff0c;欢迎提出你的想法。 是否考虑过跟开发者一对一&#xff0c;提出你的建议&#xff08;狗头&#xff09;。 https://wwxc.lanzouo.com/idKnJ2uvq11c 密码:bbkm

Unity AI-使用Ollama本地大语言模型运行框架运行本地Deepseek等模型实现聊天对话(二)

一、使用介绍 官方网页&#xff1a;Ollama官方网址 中文文档参考&#xff1a;Ollama中文文档 相关教程&#xff1a;Ollama教程 使用版本&#xff1a;Unity 2022.3.53f1c1、Ollama 0.6.2 示例模型&#xff1a;llama3.2 二、运行示例 三、使用步骤 1、创建Canvas面板 具体…

从 BERT 到 GPT:Encoder 的 “全局视野” 如何喂饱 Decoder 的 “逐词纠结”

当 Encoder 学会 “左顾右盼”&#xff1a;Decoder 如何凭 “单向记忆” 生成丝滑文本&#xff1f; 目录 当 Encoder 学会 “左顾右盼”&#xff1a;Decoder 如何凭 “单向记忆” 生成丝滑文本&#xff1f;引言一、Encoder vs Decoder&#xff1a;核心功能与基础架构对比1.1 本…

数据结构入门:详解顺序表的实现与操作

目录 1.线性表 2.顺序表 2.1概念与结构 2.2分类 2.2.1静态顺序表 2.2.2动态顺序表 3.动态顺序表的实现 3.1.SeqList.h 3.2.SeqList.c 3.2.1初始化 3.2.2销毁 3.2.3打印 3.2.4顺序表扩容 3.2.5尾部插入及尾部删除 3.2.6头部插入及头部删除 3.2.7特定位置插入…

LeetCode热题100--53.最大子数组和--中等

1. 题目 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&…

python:练习:2

1.题目&#xff1a;统计一篇英文文章中每个单词出现的次数&#xff0c;并按照出现次数排序输出。 示例输入&#xff1a; text "Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991…

AI Agent 孵化器?开源框架CAMEL

简介 CAMEL&#xff08;Communicative Agents for Mind Exploration of Large Scale Language Model Society&#xff09;是一个开源框架&#xff0c;大语言模型多智能体框架的先驱者。旨在通过角色扮演和自主协作&#xff0c;探索大语言模型&#xff08;LLM&#xff09;在多智…

关于插值和拟合(数学建模实验课)

文章目录 1.总体评价2.具体的课堂题目 1.总体评价 学校可以开设这个数学建模实验课程&#xff0c;我本来是非常的激动地&#xff0c;但是这个最后的上课方式却让我高兴不起哦来&#xff0c;因为老师讲的这个内容非常的简单&#xff0c;而且一个上午的数学实验&#xff0c;基本…

LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding

TL;DR 2024 年 Meta FAIR 提出了 LayerSkip&#xff0c;这是一种端到端的解决方案&#xff0c;用于加速大语言模型&#xff08;LLMs&#xff09;的推理过程 Paper name LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding Paper Reading Note Paper…

解决ktransformers v0.3 docker镜像中 operator torchvision::nms does not exist 问题

问题背景 更新ktransformers docker镜像到v0.3版本后&#xff08;之前为v0.2.4post1&#xff09;&#xff0c;使用更新前启动命令无法正确启动服务&#xff0c;提示以下错误&#xff1a; Traceback (most recent call last):File "/workspace/ktransformers/ktransforme…

如何系统学习音视频

学习音视频技术涉及多个领域&#xff0c;包括音频处理、视频处理、编码解码、流媒体传输等。 第一阶段&#xff1a;基础知识准备 目标&#xff1a;掌握音视频学习所需的计算机科学和数学基础。 计算机基础 学习计算机网络基础&#xff08;TCP/IP、UDP、HTTP、RTSP等协议&#…