Go GORM实战(二) | 数据库连接的N种方式
连接数据库
使用GORM连接数据库还是比较简单的,概括起来就是以下三个步骤:
-
引入
gorm.io/gorm和对应数据库的驱动库,如gorm.io/driver/sqlite。 -
调用对应驱动库的Open()或New()函数返回一个实现了gorm.Dialector接口的实例。
-
调用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中,可以通过两种方式注册组件:局部注册和全局注册。 局部注册是在父组件中通过import和components选项注册的组件,仅在当前父组件及其子组件中可用。 // 父组件中import ChildComponent from ./ChildComponent.vue;export default {co…...
HNU-算法设计与分析-作业5
第五次作业【回溯算法】 文章目录 第五次作业【回溯算法】<1> 算法分析题5-3 回溯法重写0-1背包<2> 算法分析题5-5 旅行商问题(剪枝)<3> 算法实现题5-2 最小长度电路板排列问题<4> 算法实现题5-7 n色方柱问题<5> 算法实现…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
