DM8是100%自主研发的大型通用关系型数据库,具备极致兼容性、高可用性、高可靠性和高安全性,同时支持Oracle、MySQL等数据库的兼容与迁移。
本次实践的项目是一个基于gin+mysql+redis+gorm+viper开发的日程提醒demo,在本次实践过程中需要将MySQL数据库迁移至dm8,同时需要使用dm8提供的gorm方言包并修改少量代码以完成迁移工作。
达梦数据迁移工具DMDTS具备全场景迁移能力,可支持主流大型数据库向DM迁移、DM数据库间迁移、文件向DM迁移及DM向文件迁移等核心功能。
DM数据库对主流大型关系型数据库具备业界领先的兼容性,从存储、语法到接口层面均实现高度兼容,为迁移工作奠定了坚实基础。而DMDTS工具采用图形化界面设计,以向导式流程逐步引导迁移操作,这种 “高兼容性 + 便捷工具” 的组合,大幅降低了迁移门槛,让复杂的数据库移植工作变得高效且简单。
本次迁移将采用DMDTS工具一图形化的方式将对应数据库迁移至DM
注意:在开始迁移前需要做好停止服务的准备,确认好需要迁移的数据并进行好备份
达梦驱动一般在安装目录的drivers文件夹下,我们需要在drivers文件夹中找到go文件夹,里面就是对应go驱动和gorm方言包,这里需要将它们解压
我们需要将达梦go驱动和gorm方言包移动至go安装目录的src文件夹下,这里go安装目录为D:\golang,因此需要将对应文件夹移动至D:\golang\src
接下来我们需要对源代码进行简单改动即可完成项目数据库迁移至DM8的工作
注意:在修改代码前记得保存一个版本方便出错后代码可以回退
由于本项目采用了viper处理配置文件,因此需要将原有配置文件的MySQL数据库部分修改成对应DM数据库
原有配置文件:
mysql:
host: 127.0.0.1
port: 3306
username: root
password: 123456
name: gin_calendar
修改过后
dm:
host: 127.0.0.1
port: 5236
username: SYSDBA
password: Dameng123
schema: gin_caldendar
这里需要导入对应gorm驱动并修改数据库连接与初始化的相关代码。gorm又分为V1:github.com/jinzhu/gorm 和V2:gorm.io/gorm两个版本。两个版本的gorm互相不兼容,达梦数据库也分别提供了2套方言包进行适配。这里原项目采用gorm.io/gorm的版本,因此导入V2版本的方言包
原有包导入
import (
"fmt"
"github.com/go-redis/redis/v8"
"github.com/spf13/viper"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
修改过后
import (
"fmt"
dmdialect "dmgorm2" // 导入V2方言包
"github.com/go-redis/redis/v8"
"github.com/spf13/viper"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
在完成导入后需要修改原有数据库连接的相关代码,仅需对原有连接MySQL完成简单修改即可
原有mysql连接与初始化相关代码
var DB *gorm.DB
func InitDB() *gorm.DB {
host := viper.GetString("mysql.host")
port := viper.GetString("mysql.port")
database := viper.GetString("mysql.name")
username := viper.GetString("mysql.username")
password := viper.GetString("mysql.password")
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
username,
password,
host,
port,
database)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(fmt.Sprintf("Failed to connect to database: %v", err))
}
DB = db
return db
}
修改过后代码
var DB *gorm.DB
func InitDB() *gorm.DB {
// 从配置文件获取DM8数据库连接信息
host := viper.GetString("dm.host")
port := viper.GetString("dm.port")
username := viper.GetString("dm.username")
password := viper.GetString("dm.password")
schema := viper.GetString("dm.schema")
// 构建DM8数据库连接字符串
// 格式:dm://用户名:密码@主机:端口/?schema=模式名
dsn := fmt.Sprintf("dm://%s:%s@%s:%s/?schema=%s",
username,
password,
host,
port,
schema)
config := dmdialect.Config{
DSN: dsn,
GormMode: 1, // 引入达梦新驱动的特性,构造出兼容 duplicate 语法的语句块
}
dialector := dmdialect.New(config)
// 连接DM8数据库
db, err := gorm.Open(dialector,
&gorm.Config{Logger: logger.Default.LogMode(logger.Info)})
if err != nil {
panic(fmt.Sprintf("Failed to connect to DM8 database: %v", err))
}
DB = db
return db
}
由于迁移过程中选择了保持对象名大小写,达梦数据库在实例初始化时也有字符串比较大小写敏感选项,因此sql中对应字段名和表名等最好需要使用双引号包裹。这里以通过邮箱查询用户的函数GetUserByEmail为例:
函数GetUserByEmail原有代码
func GetUserByEmail(email string) (*UserBasic, error) {
db := GetDB()
var ub UserBasic
if err := db.Where("email = ?", email).First(&ub).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &ub, nil
}
修改后代码
func GetUserByEmail(email string) (*UserBasic, error) {
db := GetDB()
var ub UserBasic
if err := db.Where("\"email\" = ?", email).First(&ub).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &ub, nil
}
注意双引号需要进行转义才能正常使用,且如果字段与达梦保留字和关键字不冲突的话这一步也可以不用做
在完成修改后启动对应服务并通过api工具验证功能是否正常
登录接口测试:
接口在完成数据库迁移后可以正常使用。
新增日程接口测试:
用户日程列表接口测试:
修改用户日程接口测试:
文章
阅读量
获赞
