发布日期:2025-06-28 15:18 点击次数:201
花样中要作念国产化sm 调教,MySQL要替换成达梦8数据库。花样中MySQL的建表语句和内置数据通过.sql文献爱戴,安设时会运滚动表结构和表内置数据。花样架构为SpringBoot + JPA / Mybatis。适配责任实质包括数据库迁徙、数据导出、花样中的成立改动和有关问题贬责有野心。
2. 数据处理历程1. 前期装备1. 安设达梦8数据库达梦官网有提供安设包,笔据我方的场景进行采用,linux_x86或者linux_aarch64,由于咱们花样要全面国产化,是以职业器用的国产华为的鲲鹏职业器(aarch64),操作系统为国产星河麒麟V10。安设法子按官网提供的文档就行,下载后安设包里也会有一些PDF确认文档可参考。
2. 创建库,启动安设时如果采用了图形化界面安设,则有DM数据库成立助手器具,可用此器具来创建数据库实例,成立的话中间有个大小写是否敏锐成立,此成立默许采用不敏锐,不然可能背面会有坑(背面说),安设时记起把客户端也选上,背面用其客户端进行操作,其他成立的话默许就行。安设完成后其中默许用户为SYSDBA,默许端口为5236。linux环境创建数据库实例传送:dm实例创建法子
2. 库数据处理这一步的处理主如果将之前花样中存储的.sql文献中MySQL的表结构和表数据有关sql调度为达梦数据库所解救的sql,况且相似保存为.sql文献,后续花样运行之前径直用sql文献进行建表导数据等运滚动操作。轻视想想如下:
1.先把之前sql文献(MySQL)导入到MySQL数据库中
2.支配达梦的数据迁徙器具把MySQL库中的数据迁徙到达梦数据库中
3.支配达梦数据库迁徙器具把达梦数据库中的数据导出到sql文献,此时sql文献中的sql语句就可在达梦数据库中推行
1. 数据迁徙如果安设时采用安设了客户端器具,则会生成一些客户端操作器具,如迁徙器具、DM管制器具、SQL交互式查询器具等。迁移时采用DM数据迁徙器具,按照器具内的法子,采用MySQL职业和数据库以及要迁徙的DM数据库。
图片
1.新建迁徙,按需采用,我这边是MySQL -> DM。
2.采用数据源迁移时不错指定Mysql数据库的驱动,成立一下jdbc驱动和联接参数即可。达梦的话即是用默许驱动即可。
图片
3.迁徙战略,可采用保合手对象名大小写,如果MySQL中表字段有效到json类型的字段时,需要手动成立一下类型映射筹办,将JSON转成VARCHAR,并树立长度,因为达梦没不解救json类型,迁移时他会默许转成VARCHAR,可是长度会变得很大(具体健忘了),这时某些场景查询时会报错,成立成8188即可,按图成立即可
图片
图片
4.背面采用迁徙模式的话全选即可,没什么需要寥落持重的点
2.数据导出第三步迁徙完成后,此时达梦数据库依然有和MySQL同名的库(dm中是schema认识)和表数据了。接下来要把库中的数据导出为.sql文献,到时辰放到花样中安设时用来运滚动表及数据。
此时仍然需要用达梦的数据迁徙器具,新建数据迁徙,采用数据迁徙方式为DM -> SQL,然后指定需要迁徙的数据源(达梦中的scheme),然后导出到野心文献即可。
图片
3. 花样适配(重心)1. 库名问题问题:导出后的达梦sql剧本你会发现,建表语句姿首为schema.table,况且主键自增重要字酿成了IDENTITY。花样中如果用SYSDBA用户联接或者别的用户联接时,推行sql语句齐要加上schema(不错相识为mysql的库名,后续就说库名了),如select * from “MY_DB”.“T_USER_TEST”,如不加库名则会报错,天然不可能把花样中整个的sql齐改一遍
-- mysql CREATE TABLE `T_USER_TEST` ( "id" BIGINT NOT NULL AUTO_INCREMENT,//主键自增 "name" VARCHAR(255) NULL );
-- 达梦 CREATE TABLE "MY_DB"."T_USER_TEST" ( "id" BIGINT IDENTITY(1,2) NOT NULL,//主键自增 "name" VARCHAR(255) NULL );
贬责有野心:创建一个用户,用户名为库名,创建用户后达梦会自动创建一个和用户名接头的库,此时用此用户登录联接,推行sql语句时表名前边就不需要加库名了,因为他默许查的即是此用户下的库。语句如下(包括创建表空间、赋权等),后续联接时使用此账号和密码以及url联接中的schema(MY_DB)
-- 创建表空间MY_DB CREATE tablespace MY_DB DATAFILE 'MY_DB.DBF' SIZE 128; -- 创建用户MY_DB,密码为123456,此时会自动创建名为MY_DB的schema CREATE USER "MY_DB" IDENTIFIED BY "123456" DEFAULT tablespace MY_DB; -- 为MY_DB用户赋权 grant "DBA","RESOURCE","PUBLIC","SOI" to "MY_DB" with admin option; grant EXECUTE on "SYS"."DBMS_XMLGEN" to "MY_DB";
Spring数据库联接成立参考:
#dm8联接 spring.datasource.url=jdbc:dm://127.0.0.1:5236/MY_DB spring.datasource.username=MY_DB spring.datasource.password=123456 spring.datasource.driver-class-name=dm.jdbc.driver.DmDriver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource #如果花样中有使用到JPA,参考如下方言成立 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.DmDialect spring.jpa.properties.hibernate.hbn2ddl.auto=none spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false2. 主键自增问题1. 问题分解
最初,达梦数据库是解救主键自增的,DDL中自增重要字为IDENTITY,假如咱们表中的id字段树立的为自增id,insert语法常见如下三种:
-- 如下建表语句,id为自增id CREATE TABLE "MY_DB"."t_user_test" ( "id" BIGINT IDENTITY(1,2) NOT NULL,//主键自增 "name" VARCHAR(255) NULL ); -- 1.insert的正确姿势,此时会生成则增id insert into "t_user_test"(name) values("tom"); -- 2.纰缪示范,此时会报错:仅当指定列列表,且SET IDENTITY_INSERT为ON时,武艺对自增列赋值 insert into "t_user_test"(id,name) values(1,"tom"); -- 3.纰缪示范,此时会报错: 仅当指定列列表,且SET IDENTITY_INSERT为ON时,武艺对自增列赋值或者违背列[id]非空欺压 insert into "t_user_test"(id,name) values(null,"tom");
1.第一种插入没问题,无可厚非
2.第二种插入会报错,意旨真谛即是说,你的id树立的为自增列,可是你插入时对自增列手动赋值,这是不允许的,树立了自增就应该用数据库的自增生成。可是花样中不免有手动树立id插入的场景,此时亦然有贬责有野心的,即是在插入之前树立IDENTITY_INSERT为ON。持重IDENTITY_INSERT重要字是表级别的重要字,语法要指定到表,弗成对全库进行树立。
-- 树立t_user_test表 SET IDENTITY_INSERT MY_DB.t_user_test ON insert into("id","name") values(1,"tom"); -- OFF不错装假践,不影响 SET IDENTITY_INSERT MY_DB.t_user_test OFF
针对IDENTITY_INSERT问题,本东谈主作念了一些测试,得出以下论断供参考:
如需要使用数据库主键自增特点,需要在主键列上声明IDENTITY
当insert语句时,如果手动树立id值,则需要树立此表的IDENTITY_INSERT为 ON
推行完不关闭(SET IDENTITY_INSERT MY_DB.t_user_test OFF),再次插入id为空的值如故不错自增的
不同会话之间推行SET IDENTITY_INSERT MY操作不会彼此影响
兼并会话兼并工夫只可有一张表IDENTITY_INSERT 树立为ON,背面会遮盖前边的,兼并会话屡次树立只须临了一次树立收效
当insert语句中,如果id泄露插入,况且value为null,则会报非空欺压的问题
开启语句:SET IDENTITY_INSERT db.table ON
关闭语句:SET IDENTITY_INSERT db.table OFF
3.第三种插入报错很显着,当你莫得树立IDENTITY_INSERT时,他会先报错让你对其树立为ON,如果树立完后就会报错违背id非空欺压,因为id建表时为主键,自带非空欺压。弗成泄露插入null值,此种纰缪只可对sql进行处理,背面会讲。
2. 问题处理经过以上问题分析,insert某张表时,不错先树立IDENTITY_INSERT为ON,诚然只须第一种insert不需要树立,不错径直走自增,可是你树立后也不会影响insert的推行,为了偷懒不想整理花样中的sql,索性整个insert齐树立IDENTITY_INSERT为ON。天然你不错写sql,修改花样中的代码,在整个insert操作之前齐推行一遍INDENTITY_INSERT ON,可是代码中合手久层框架用了JPA和Mybatis,况且此类sql许多,是以接管AOP的方式贬责。
文爱社区JPA贬责想路:在咱们花样中使用JPA保存对象竣事插入齐是波折调用JpaRepository.save()措施,是以在此措施加一层禁绝处理就行了sm 调教,推行save之前先推行SET IDENTITY_INSERT ON,参考代码如下:
@Aspect @Component public class JpaSaveAspect { public static final String IDENTITY_INSERT_ON = "SET IDENTITY_INSERT MY_DB.%s ON"; public static final String IDENTITY_INSERT_OFF = "SET IDENTITY_INSERT MY_DB.%s OFF"; @Autowired private JdbcTemplate jdbcTemplate; // 节点为JpaRepository.save @Pointcut("execution(* org.springframework.data.jpa.repository.JpaRepository.save(..))") public void savePointcut() { } //推行切点措施之前要进行的处理 @Before("savePointcut()") public void beforeSave(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); if (Objects.isNull(args)