当前位置: 首页 > news >正文

Go GORM实战(二) | 数据库连接的N种方式

连接数据库

使用GORM连接数据库还是比较简单的,概括起来就是以下三个步骤:

  1. 引入gorm.io/gorm和对应数据库的驱动库,如gorm.io/driver/sqlite

  2. 调用对应驱动库的Open()或New()函数返回一个实现了gorm.Dialector接口的实例。

  3. 调用gorm.Open()方法传入一个gorm.Dialector接口的实例以初始一个gorm.DB对象。

通过上述三个步骤,最终获取一个gorm.DB对象,我们便可以使用该对象的方法操作数据库,如Create,Delete等方法。

MySQL

简单连接

下面是连接mysql数据库最简单的方式,我们只需要定义好dsn便可以了 

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc main() {//user、password、IP、port、dbnamedsn := "user:password@tcp(ip:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{SkipDefaultTransaction:                   false, //设置为 false 表示不跳过默认事务NamingStrategy:                           nil,   //设置为 nil,表示使用 GORM 的默认命名策略FullSaveAssociations:                     false, //设置为 false 表示不完整保存关联的记录Logger:                                   nil,   //设置为 nil,表示不设置自定义的日志记录器NowFunc:                                  nil,   //设置为 nil,表示使用 GORM 的默认时间函数DryRun:                                   false, //设置为 false,表示不执行模拟运行PrepareStmt:                              false, //设置为 false,表示不预先准备语句DisableAutomaticPing:                     false, //设置为 false,表示不禁用自动心跳检测DisableForeignKeyConstraintWhenMigrating: false, //设置为 false,表示在迁移时不禁用外键约束IgnoreRelationshipsWhenMigrating:         false, //设置为 false,表示在迁移时不忽略关系DisableNestedTransaction:                 false, //设置为 false,表示不禁用嵌套事务AllowGlobalUpdate:                        false, //设置为 false,表示不允许全局更新QueryFields:                              false, //设置为 false,表示不使用字段查询CreateBatchSize:                          0,     //设置为 0,表示使用 GORM 的默认批量创建大小TranslateError:                           false, //设置为 false,表示不转换错误ClauseBuilders:                           nil,   //设置为 nil,表示不设置自定义的查询子句构建器ConnPool:                                 nil,   //设置为 nil,表示使用 GORM 的默认连接池Dialector:                                nil,   //设置为 nil,表示使用 GORM 的默认方言(dialect)Plugins:                                  nil,   //设置为 nil,表示不使用任何插件})if err != nil {panic("数据库连接错误")}DB = db
}
mysql.New

如果我们在连接数据库时,想进一步配置,则可以使用mysql.New()函数,该函数可以传递一个mysql.Config进行详细配置,如:

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc main() {//user、password、IP、port、dbnamedsn := "user:password@tcp(ip:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"//db, err := gorm.Open(mysql.New(mysql.Config{//	DSN:                       dsn,   // DSN data source name//	DefaultStringSize:         256,   // string 类型字段的默认长度//	DisableDatetimePrecision:  true,  // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持//	DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引//	DontSupportRenameColumn:   true,  // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列//	SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置//}))db, err := gorm.Open(mysql.New(mysql.Config{DriverName:                    dsn,   //驱动程序的名称,通常不需要手动设置,GORM 默认使用 mysqlServerVersion:                 "",    //服务器版本,通常在连接成功后由 GORM 自动设置DSN:                           "",    //数据源名称,这是一个包含数据库连接信息的字符串,格式通常为 username:password@tcp(address:port)/dbname?param=valueDSNConfig:                     nil,   //一个 mysql.DSNConfig 类型的配置,用于进一步配置 DSN 字符串Conn:                          nil,   //一个原始的连接对象,通常不需要手动设置SkipInitializeWithVersion:     false, //设置为 false 表示不跳过使用服务器版本进行初始化DefaultStringSize:             0,     //默认的字符串大小,设置为 0 表示使用 GORM 的默认值DefaultDatetimePrecision:      nil,   //默认的 datetime 精度,这里设置为 nil,表示使用 GORM 的默认值DisableWithReturning:          false, //设置为 false 表示不禁用 WITH RETURNING 支持DisableDatetimePrecision:      false, //设置为 false 表示不禁用 datetime 精度支持DontSupportRenameIndex:        false, //以 DontSupport 开头的字段:这些字段表示是否不支持某些特定的数据库功能,这里全部设置为 false,表示没有禁用任何功能DontSupportRenameColumn:       false, //DontSupportForShareClause:     false, //DontSupportNullAsDefaultValue: false, //DontSupportRenameColumnUnique: false, //DontSupportDropConstraint:     false, //}))if err != nil {panic("数据库连接错误")}DB = db
}
通过sql.DB初始化*gorm.DB

如果我们自己使用database/sql打开一个数据库连接,那么也可以利用这个已经存在的连接,来初始化一个gorm.DB对象, 如:

package mainimport ("database/sql""gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc main() {db, err := sql.Open("mysql", "root:123qwe@tcp(localhost:3306)/mysql_db?charset=utf8&parseTime=True&loc=Local")if err != nil {panic(err)}DB, err = gorm.Open(mysql.New(mysql.Config{Conn: db,}))//都可以增删改查//db.Query("")//DB.Find("")
}

 PostgreSQL

简单连接
package mainimport ("gorm.io/driver/postgres" //驱动库"gorm.io/gorm"
)func main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"db, err := gorm.Open(postgres.Open(dsn))if err != nil {panic(err)}db.Exec("")
}
 postgres.New
package mainimport ("gorm.io/driver/postgres""gorm.io/gorm"
)func main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"db, err := gorm.Open(postgres.New(postgres.Config{DSN:                  dsn,PreferSimpleProtocol: true,}))if err != nil {panic(err)}db.Exec("")
}
 通过sql.DB初始化*gorm.DB
package mainimport ("database/sql""gorm.io/driver/postgres""gorm.io/gorm"
)var DB *gorm.DBfunc main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"sqlDB, _ := sql.Open("pgx", dsn)db, err := gorm.Open(postgres.New(postgres.Config{Conn:                 sqlDB,PreferSimpleProtocol: true,}))if err != nil {panic(err)}DB = db
}

SQL Server

简单连接
package mainimport ("gorm.io/driver/sqlserver""gorm.io/gorm"
)func main() {dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db, err := gorm.Open(sqlserver.Open(dsn))if err != nil {panic(err)}
}
 sqlserver.New
package mainimport ("gorm.io/driver/sqlserver""gorm.io/gorm"
)func main() {dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db, err := gorm.Open(sqlserver.New(sqlserver.Config{DSN: dsn,}))
}
 通过sql.DB初始化*gorm.DB 
package mainimport ("database/sql""gorm.io/driver/sqlserver""gorm.io/gorm"
)func main() {dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"sqlDB, _ := sql.Open("sqlserver", dsn)db, err := gorm.Open(sqlserver.New(sqlserver.Config{Conn: sqlDB,}))
}

SQLite

因为SQLite数据库其实只是一个文件而已,所以SQLite的连接非常简单,只需要传入SQLite数据库的文件路径即可,比如我们连接一个在当前目录的gorm.db数据

package mainimport ("gorm.io/driver/sqlite" //驱动库"gorm.io/gorm"
)func main() {db, err := gorm.Open(sqlite.Open("gorm.db")) //参数名随便,后缀也可以随便只要合法就可以/*SQLite 数据库文件并不一定要以 .db 为后缀名。SQLite 是一个非常灵活的数据库系统,它不关心文件的扩展名是什么。可以使用任何合法的文件名,包括但不限于 .db、.sqlite、.db3(这是 SQLite 默认的文件扩展名之一)或者其他任何您喜欢的名称*/
}

另外,连接SQLite数据库时,也可以在内存中创建临时数据库,而需要一个实际的数据库,SQLite 允许您使用特殊的语法来创建一个基于内存的数据库,这个数据库不会持久化到磁盘上,而是存储在内存中,基于内存的数据库在程序结束时会自动销毁,所有数据都会丢失。如果您需要在程序之间保留数据,您应该使用存储在磁盘上的数据库文件。

使用 :memory: 伪路径创建基于内存的数据库:
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})

使用 :memory: 会创建一个新的基于内存的数据库,每次程序运行时都会重新创建。这个数据库在程序结束时自动销毁。

使用 file::memory: 伪路径创建基于内存的数据库:
db, err := gorm.Open(sqlite.Open("file::memory:"), &gorm.Config{})

 file::memory::memory: 相似,也是创建基于内存的数据库。但是,file::memory: 允许 SQLite 使用更多的文件接口功能。

使用 file::memory:?cache=shared 创建共享缓存的基于内存数据库:
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})

使用 cache=shared 参数可以创建一个所有数据库连接都共享同一数据库状态缓存的基于内存数据库。这可以提高并发访问数据库的性能。

 gorm.Config

gorm.Config实现了Option接口,因此我们可以将gorm.Config传递给gorm.Open函数,gorm.Config的源码 

// Config GORM config
type Config struct {//跳过默认事务SkipDefaultTransaction bool// 命名策略,可以定义表名,列表等生成规则NamingStrategy schema.Namer// 在创建或更新时,是否更新关联数据FullSaveAssociations bool// 日志接口,用于实现自定义日志Logger logger.Interface// 创建时间使用的函数NowFunc func() time.Time// 生成 SQL 但不执行,可以用于准备或测试生成的 SQLDryRun bool// 是否禁止创建 prepared statement 并将其缓存PrepareStmt bool// 禁止去ping数据库,检测是否可用DisableAutomaticPing bool// 是否禁止自动创建外键约束DisableForeignKeyConstraintWhenMigrating bool// 是否禁止嵌套事务DisableNestedTransaction bool// 是否允许全局update/deleteAllowGlobalUpdate bool// 执行查询时,是否带上所有字段QueryFields bool// 默认批量插入大小CreateBatchSize int
}

 连接池

通过数据库连接池,我们可以避免频繁创建和销数据库连接所带来的开销,GROM的数据连接池底层是通过database/sql来实现的,所以其设置方法与database/sql是一样的 

sqlDB, err := db.DB()// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)

 关闭数据库

程序执行结束后,需要关闭数据连接,而GORM的底层仍然是通过database/sql去连接数据库的,因此要通过gorm.DB对象的DB()方法返回的sql.DB来关闭数据库连接

sqlDB, err := db.DB()sqlDB.Close()//defer sqlDB.Close()

 

相关文章:

Go GORM实战(二) | 数据库连接的N种方式

连接数据库 使用GORM连接数据库还是比较简单的,概括起来就是以下三个步骤: 引入gorm.io/gorm和对应数据库的驱动库,如gorm.io/driver/sqlite。 调用对应驱动库的Open()或New()函数返回一个实现了gorm.Dialector接口的实例。 调用gorm.Open…...

Cocos Creator 2D Mask与Layout 使用详解

Cocos Creator是一款强大的2D游戏开发引擎,提供了丰富的功能和工具,使开发者可以轻松创建出高质量的游戏。其中,2D Mask和Layout是Cocos Creator中常用的两个组件,它们可以帮助开发者实现更加复杂和精美的游戏界面设计。本文将详细…...

项目-坦克大战

增加功能 我方坦克在发射的子弹消亡后,才能发射新的子弹。同时实现发多颗子弹 1,在按下J键,我们判断当前hero对象的子弹,是否已经销毁2,如果没有销毁,就不去触发shotEnemyTank3,如果已经销毁&…...

代码随想录算法训练营第二十九天| LeetCode491.递增子序列* 、LeetCode46.全排列*、LeetCode47.全排列 II

#LeetCode 491. Non-decreasing Subsequences #LeetCode 491. 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili 首先,本题不能考虑首先对数组排序,排序会导致数组直接变为一个…...

基于SpringBoot设计模式之开端

文章目录 前言引言开始 前言 为了更好的在项目中,能更加优雅的使用设计模式,比较针对性的解决我们的问题。我将在这个专栏详细的描述23种设计模式,为了与时俱进,我打算通过springboot的形式将23种设计模式全部撸完! 引…...

tensorflow实现二分类

# 导入所需库和模块 from tensorflow.keras.layers import Dense, Input, Activation # 导入神经网络层和激活函数模块 from tensorflow.keras.models import Sequential # 导入Keras的Sequential模型 import pandas as pd # 导入Pandas库用于数据处理 import numpy as np …...

简化路径[中等]

优质博文:IT-BLOG-CN 一、题目 给你一个字符串path,表示指向某一文件或目录的Unix风格 绝对路径 (以/开头),请你将其转化为更加简洁的规范路径。在Unix风格的文件系统中,一个点.表示当前目录本身&#x…...

记一次若依项目组装树型结构数据的效率优化

背景 最近公司的项目使用了若依框架做开发,发现部门管理功能的部门如果有3万笔记录时,查询部门信息并组装为父子结构时运行特别缓慢,本地运行需要3分钟才能加载出来,因此接到优化的工作。 代码展示 首先看看表结构是这么定义的…...

秒杀系统之系统优化

3 系统优化 对于一个软件系统,提高性能可以有很多种手段,如提升硬件水平、调优JVM 性能,这里主要关注代码层面的性能优化—— 减少序列化:减少 Java 中的序列化操作可以很好的提升系统性能。序列化大部分是在 RPC 阶段发生&#x…...

【介绍下Python多线程,什么是Python多线程】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...

FPGA相关论文阅读

一、Achieving 100Gbps Intrusion Prevention on a Single Server 论文名称中文翻译:在单台服务器上实现100Gbps吞吐量的入侵防御检测。 文章中的Mixed-1和Norm-1 二、Distributed Password Hash Computation on Commodity Heterogeneous Programmable Platforms…...

瑞芯微RK3588驱动设计之DVP并口摄像头2

dts配置看瑞芯微RK3588驱动配置之DVP并口摄像头1_rockchip 调试dvp设备 直接显示摄像头数据-CSDN博客 这里看看驱动的具体实现,以gc2145为例。 gc2145的驱动源码如下: // SPDX-License-Identifier: GPL-2.0 /** GC2145 CMOS Image Sensor driver*** C…...

安卓手机APP开发__支持64位的架构

安卓手机APP开发__支持64位的架构 目录 概述 读取你的APP 快速的状态检查 你的APP使用了原生的代码吗? 你的APP包含了64位的代码库吗? 确保在这些目录中有原生的代码库. 使用APK分析器查看原生的代码库 通过解压缩APK查看原生的代码库 用安卓工…...

Foxmail使用经验总结

目录 1.概述 2.版本历史 3.使用方法 3.1.安装和设置账户 3.2.收取和阅读邮件 ​​​​​​​3.3.发送邮件 ​​​​​​​3.4.管理联系人 ​​​​​​​3.5.日程安排和任务管理 ​​​​​​​3.6.定制设置和插件 ​​​​​​​3.7.跨平台同步 4.小结 1.概述 Fox…...

信息系统项目管理师0601:项目立项管理 — 考点总结(可直接理解记忆)

点击查看专栏目录 项目立项管理 — 考点总结(可直接理解记忆) 1.项目建议书(又称立项申请)是项目建设单位向上级主管部门提交项目申请时所必须的文件,是对拟建项目提出的框架性的总体设想。在项目建议书批准后,方可开展对外工作(掌握)。 2.项目建议书应该包括的核心内…...

实验三:机器学习1.0

要求: 针对实验1和实验2构建的数据集信息分析 设计实现通过数据简介进行大类分类的程序 代码实现: 训练集数据获取: read_data.py import json import pickledef read_intro():data []trypathr"E:\Procedure\Python\Experiment\f…...

Vue 3 + Vite项目实战:常见问题与解决方案全解析

文章目录 一、项目使用本地图片打包后不显示1、在html中时候,本地运行和打包后线上运行都ok。2、用动态数据,本地运行ok,打包后线上运行不显示3、适用于处理单个链接的资源文件4、用动态数据且本地和线上访问都可显示 二、使用插件vite-plugi…...

飞天使-k8s知识点31-rancher的正确打开方式

文章目录 安装之前优化一下内核参数以及系统内核版本 rancher安装主要是使用以下命令nginx的配置为解决办法 安装之前优化一下内核参数以及系统内核版本 内核版本 4.17 cat > /etc/modules-load.d/iptables.conf <<EOF ip_tables iptable_filter EOF 然后重启服务器…...

Vue.component v2v3注册(局部与全局)组件使用详解

在Vue中&#xff0c;可以通过两种方式注册组件&#xff1a;局部注册和全局注册。 局部注册是在父组件中通过import和components选项注册的组件&#xff0c;仅在当前父组件及其子组件中可用。 // 父组件中import ChildComponent from ./ChildComponent.vue;export default {co…...

HNU-算法设计与分析-作业5

第五次作业【回溯算法】 文章目录 第五次作业【回溯算法】<1> 算法分析题5-3 回溯法重写0-1背包<2> 算法分析题5-5 旅行商问题&#xff08;剪枝&#xff09;<3> 算法实现题5-2 最小长度电路板排列问题<4> 算法实现题5-7 n色方柱问题<5> 算法实现…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...