北条麻妃出租车 国产适配之MySQL替换为达梦8数据库

发布日期:2024-09-07 03:57    点击次数:133
1. 布景

神气中要作念国产化,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=false
2. 主键自增问题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()门径,是以在此门径加一层阻挡处理就行了,扩充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)