当前位置: 首页 > 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> 算法实现…...

甲言(Jiayan):终极古汉语NLP工具包的完整使用指南

甲言&#xff08;Jiayan&#xff09;&#xff1a;终极古汉语NLP工具包的完整使用指南 【免费下载链接】Jiayan 甲言&#xff0c;专注于古代汉语(古汉语/古文/文言文/文言)处理的NLP工具包&#xff0c;支持文言词库构建、分词、词性标注、断句和标点。Jiayan, the 1st NLP toolk…...

3步破解微信记录管理难题:WeChatMsg如何重新定义数字记忆保存?

3步破解微信记录管理难题&#xff1a;WeChatMsg如何重新定义数字记忆保存&#xff1f; 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHu…...

GLM-4-9B-Chat-1M惊艳效果:1M token混合中英文技术文档中精准分离双语术语表

GLM-4-9B-Chat-1M惊艳效果&#xff1a;1M token混合中英文技术文档中精准分离双语术语表 想象一下&#xff0c;你手头有一份200万字的技术文档&#xff0c;中英文混杂在一起&#xff0c;专业术语随处可见。传统方法需要人工逐页翻阅&#xff0c;耗时耗力还容易出错。现在&#…...

鸿蒙系统终极阅读神器:开源阅读如何彻底改变你的数字阅读体验

鸿蒙系统终极阅读神器&#xff1a;开源阅读如何彻底改变你的数字阅读体验 【免费下载链接】legado-Harmony 开源阅读鸿蒙版仓库 项目地址: https://gitcode.com/gh_mirrors/le/legado-Harmony 你是否厌倦了商业阅读应用的广告弹窗&#xff1f;是否受限于平台书库的有限内…...

教授专栏204| 潘永安:成功研发新型光探测器,促进可编程光子学应用

港科大电子及计算机工程学系系主任及教授潘永安&#xff08;左&#xff09;丶博士生牛玥&#xff08;右&#xff09;于港科大光子器件实验室合照。可编程光子学利用光传送讯号&#xff0c;能达到比电子学更快丶更节能的运算。然而&#xff0c;现有片上功率监测器的性能不足&…...

OnmyojiAutoScript:阴阳师智能自动化脚本完全指南

OnmyojiAutoScript&#xff1a;阴阳师智能自动化脚本完全指南 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师每日重复任务感到疲惫吗&#xff1f;每天花费数小时在…...

忍者像素绘卷惊艳效果展示:鸣人螺旋丸像素绘卷作品集

忍者像素绘卷惊艳效果展示&#xff1a;鸣人螺旋丸像素绘卷作品集 1. 像素艺术新纪元&#xff1a;忍者世界的视觉革命 当传统漫画遇上16-bit复古美学&#xff0c;忍者像素绘卷为我们打开了一扇通往全新视觉体验的大门。这款基于Z-Image-Turbo深度优化的图像生成工作站&#xf…...

像素剧本圣殿参数详解:Qwen2.5-14B-Instruct温度值、top_p与剧本创意波动关系

像素剧本圣殿参数详解&#xff1a;Qwen2.5-14B-Instruct温度值、top_p与剧本创意波动关系 1. 创作引擎核心参数解析 像素剧本圣殿的核心创作能力源自Qwen2.5-14B-Instruct模型&#xff0c;其中温度值(temperature)和top_p参数直接影响剧本生成的创意表现。这两个参数就像导演…...

鼎捷T100二次开发踩坑实录:修改规格后变量不自动生成怎么办?

鼎捷T100二次开发实战&#xff1a;规格修改后变量生成异常深度解析 在鼎捷T100系统的二次开发过程中&#xff0c;规格修改后的变量自动生成机制是开发者日常工作中频繁接触的核心功能之一。这个看似简单的自动化流程&#xff0c;在实际操作中却可能因为各种原因出现异常&#x…...

数字人形象哪里找?lite-avatar形象库150+角色免费使用体验

数字人形象哪里找&#xff1f;lite-avatar形象库150角色免费使用体验 1. 数字人形象获取的痛点与解决方案 在开发数字人应用时&#xff0c;寻找合适的数字人形象往往是第一个拦路虎。传统方式需要自己收集数据、训练模型&#xff0c;这个过程既耗时又耗力&#xff0c;对很多开…...