golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动

2024-02-01 20:52

本文主要是介绍golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动

最近在开发一个边缘物联网程序时使用Golang开发,用到GORM来操作SQLite数据库,GORM默认使用gorm.io/driver/sqlite这个库作为SQLite驱动,该库用CGO实现,在使用过程中遇到一些问题,编译好二进制程序放到资源受限的设备中运行,报错如下;最后更换第三方SQLite驱动解决。

github.com/mattn/go-sqlite3 这个库现在在 go 项目当中,引用最多,应用最广;俨然成为这一方面的标准,但有一个最大的问题就是,这是一个 C 语言实现的库,如果要应用这个库,那么你的环境就需要解决这个 CGO 依赖。

报错如下,正是因为GORM官方SQLite驱动使用CGO实现,因此我在使用过程中遇到以下错误:

[error] failed to initialize database, got error Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub panic: Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

大致意思是GORM SQLite驱动使用了CGO实现,需要在CGO环境下才能工作。

那么解决方法也很简单,只需要修改CGO_ENABLED这个环境变量启用CGO支持即可:

go env -w CGO_ENABLED=1

启用CGO后,编译的是动态链库的二进制文件,那么你一旦更换平台,比如将程序放到Windows下运行,可能因为缺少相关的一些动态链库(比如:SQLite)从而无法运行,为了保持编译的二进制文件能够无动态依赖的情况下正常运行,因此不得不考虑静态编译,所以就和GORM SQLite驱动产生了冲突。

很多瘦小设备,弱设备里的系统,没有相关依赖库和驱动,也很难安装相关的驱动,此时不得不考虑使用不依赖任何三方的驱动情况下运行程序。

解决方案-更换GORM默认的SQLite驱动

在GORM官方的Issues发现也有人反馈此类问题,于是顺藤摸瓜,找到了github.com/glebarez/sqlite这个库,该库使用纯go实现,不依赖CGO,地址是:https://github.com/glebarez/sqlite

使用如下驱动

import ("fmt"_ "github.com/glebarez/sqlite""github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/sqlite"
)const (dbDriverName = "sqlite"dbName       = "iot.db"
)var SqliteDb *gorm.DBfunc SqliteInit() {var err errorSqliteDb, err = gorm.Open(dbDriverName, "./"+dbName)if err != nil {fmt.Printf("connect DB failed, err:%v\n", err)return}fmt.Println("connect DB success")// 打印 SQL 语句SqliteDb.LogMode(true)// 空闲状态下的最大连接数,默认的最大空闲连接数为2SqliteDb.DB().SetMaxIdleConns(10)// 最大打开连接数, 默认值为0(无限制)SqliteDb.DB().SetMaxOpenConns(50)// 不要复数表名SqliteDb.SingularTable(true)// 自动迁移模型(创建表)//SqliteDb.AutoMigrate()
}func SqliteClose() {//关闭SqliteDb.Close()
}

这样就可以在不依赖CGO的情况下编译出静态二进制文件,从而解决跨平台依赖动态链库的问题。

代价

glebarez/sqlite性能不及官方驱动,但牺牲少部分性能来换取方便个人觉得还是值得的,如果没有跨平台需求,使用官方默认驱动即可

静态编译打包后的文件体积明显增加

参考链接:
https://blog.xiaoz.org/archives/18195
https://wiki.eryajf.net/pages/74da0a/#%E5%89%8D%E8%A8%80
https://yoby123.cn/2021/06/15/20210615-sqlite.html

这篇关于golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/668439

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

Mysql虚拟列的使用场景

《Mysql虚拟列的使用场景》MySQL虚拟列是一种在查询时动态生成的特殊列,它不占用存储空间,可以提高查询效率和数据处理便利性,本文给大家介绍Mysql虚拟列的相关知识,感兴趣的朋友一起看看吧... 目录1. 介绍mysql虚拟列1.1 定义和作用1.2 虚拟列与普通列的区别2. MySQL虚拟列的类型2

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@