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

golang gorm 增删改查以及使用原生SQL(以操作mysql为例)

gorm + mysql增删改查

model定义
package _caseimport "gorm.io/gorm"func init() {DB.Migrator().AutoMigrate(Teacher{}, Course{})
}
type Roles []stringtype Teacher struct {gorm.ModelName     string   `gorm:"size:256"`Email    string   `gorm:"size:256"`Salary   float64  `gorm:"scale:2;precision:7"`   // 指定小数部分宽度为2,列宽度为7. 列宽:【整数部分+小数部分的总长度】【不含小数点】Age      uint8    `gorm:"check:age>30"`Birthday int64    `gorm:"serializer:unixtime;type:time"`  // 反序列化方式 unixtime, 类型为timeRoles    Roles    `gorm:"serializer:json"`JobInfo  Job      `gorm:"embedded;embeddedPrefix:job_"`   // 嵌套字段, 嵌入字段的列名前缀job_JobInfo2 Job      `gorm:"type:bytes;serializer:gob"`      // 字节流类型,gob反序列化,go自己的序列化方法,跨语言项目的时候,不建议用
}type Job struct {Title    stringLocation string
}type Course struct {gorm.ModelName   string  `gorm:"size:256"`Price  float64 `gorm:"scale:2;precision:7"`UserID uint    `gorm:"type:int"`
}
数据库连接并设置连接池
package _caseimport ("gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""log""time"
)var DB *gorm.DBvar dsn = "root:123456@tcp(10.74.18.61:3306)/mydb?charset=utf8mb4&parseTime=True&loc=Local"func init() {var err error// 每次调用返回的都是DB对象,这是支持链式调用的DB, err = gorm.Open(mysql.New(mysql.Config{DSN: dsn,DefaultStringSize: 256,}), &gorm.Config{Logger: logger.Default.LogMode(logger.Info),//开启预编译,提高后续调用速度//开启预编译的情况下,不支持嵌套事务PrepareStmt: true,})if err != nil {log.Println(err)return}setPool(DB)
}// 连接池设置
func setPool(db *gorm.DB) {sqlDB, err := db.DB()if err != nil {log.Println(err)return}// 连接存活最大时长sqlDB.SetConnMaxLifetime(time.Hour)// 最大空闲连接数sqlDB.SetMaxIdleConns(5)// 最大连接打开数sqlDB.SetMaxOpenConns(10)}

假数据定义

var teacherTemp = Teacher{Name: "kk",Age: 40,Salary: 1234.22,Email: "kk123@qq.com",Birthday: time.Now().Unix(),Roles: Roles{"普通用户", "讲师"},JobInfo: Job{Title: "教授",Location: "九龙湖",},JobInfo2: Job{Title: "教授",Location: "九龙湖",},
}
插入数据
  • 插入一条/多条记录
t1 := teacherTemp 
res := DB.Create(&t) // 指针传入
  • 正向选择, 选择某些字段插入 【gorm model里的不包含】
t1 := teacherTemp
res = DB.Select("name", "age").Create(&t1)
  • 反向选择, 排除某些字段插入(忽略大小写
t2 := teacherTemp
res = DB.Omit("email", "Birthday").Create(&t2)
  • 批量,按batchsize插入
var teachers = []Teacher{{Name: "qq", Age: 50}, {Name: "pp", Age: 60}, {Name: "gg", Age: 55}, {Name: "mm", Age: 56}}
DB.CreateInBatches(teachers, len(teachers))  // 或者直接DB.Create(teachers)
  • 查找第一个匹配的记录并返回,若无匹配记录则插入
t3 := teacherTemp
t3.Name = "oo"
out := Teacher{}
res = DB.Attrs(t3).FirstOrCreate(&out, Teacher{Name: "oo"})
删除数据

gorm采用的是软删除,删除语句为update,去更新delete_at字段

  • 根据ID删除
DB.Delete(&Teacher{Model: gorm.Model{ID: 9}})

gorm输出语句(软删除)

 UPDATE `teachers` SET `deleted_at`='2023-10-09 18:51:43.901' WHERE `teachers`.`id` = 9 AND `teachers`.`deleted_at` IS NULL
  • 根据条件删除, 批量删除
DB.Where("name like ?", "yuan*").Delete(&Teacher{})
DB.Delete(&Teacher{}, []int{3,4,5,})
  • 根据主键删除(主键不一定是gorm.Model的ID)
DB.Delete(&Teacher{}, 1)
DB.Delete(&Teacher{}, []int{3,4,5,})
更新数据
  • 全部更新
teacher := Teacher{}
DB.First(&teacher)
// 更新
teacher.Age = 66
teacher.Name = "wang"
// 更新所有 save 会将所有字段保存到数据库, 无论字段有没有被改
DB.Save(teacher)
  • 更新单行数据某个列
DB.Model(&Teacher{}).Where("id = ?", teacher.ID).Update("name", "yuan")
  • 通过model指定条件更新, 只能指定ID
DB.Model(&Teacher{Model:gorm.Model{ID: teacher.ID}}).Update("name", "yuan")
  • 更新单行多个列
// 更新单行多个列 结构体方式
DB.Model(&Teacher{}).Where("id = ?", teacher.ID).Updates(Teacher{Name: "updatayuan", Age: 40})
// 更新单行多个列 map方式
DB.Model(&Teacher{}).Where("id = ?", teacher.ID).Updates(map[string]interface{}{"name": "updateY", "age": 40})
  • 批量更新 多行数据
DB.Model(&Teacher{}).Where("age > ?", 60).Updates(Teacher{Email: "update@qq.com"}) // 用map也行
  • 选定/排除某些字段更新
// 选定更新某些字段
DB.Model(&Teacher{}).Where("id = ?", 5).Select("name", "age").Updates(teacher)
// 排除某些字段 更新
DB.Model(&Teacher{}).Where("id = ?", 5).Omit("name", "age").Updates(teacher)
查询
简单查询
  • 单记录查询
func GetOnce() {t := Teacher{}// 查询一条// 获取主键排序第一条DB.First(&t)// 无排序规则 取第一条t = Teacher{}DB.Take(&t)// 主键排序最后一条t = Teacher{}DB.Last(&t)//查询结果填充到集合中result := map[string]interface{}{}// 可能会有特殊类型不好处理,无法完成类型转换,可以忽略一些字段DB.Model(&Teacher{}).Omit("Birthday", "Roles", "JobInfo2").First(&result)// 基于表名 查询记录result = map[string]interface{}{}DB.Table("teachers").Take(&result)}
  • 根据字符串条件获取记录
func GetByStrCond() {t := Teacher{}var teaches []TeacherDB.Find(&teaches, "name IN ?", []string{"yuan", "oo", "gg"})DB.Where("name = ?", "gg").First(&t)DB.Where("name IN ?", []string{"yuan", "oo"}).Find(&teaches)
}
  • 通过结构体或集合指定条件查询
func GetByStructOrMapCond() {var teachers []Teachert := Teacher{}//structDB.Find(&teachers, Teacher{Name: "oo", Age: 40})// mapDB.Find(&teachers, map[string]interface{}{"Name": "gg", "Age": 40})DB.Where(Teacher{Name: "yuan", Age: 40}).First(&t)DB.Where(map[string]interface{}{"Name": "qq", "Age": 40}).Find(&teachers)DB.Where([]int{10, 11, 12}).Find(&teachers)//指定查询条件使用的字段DB.Where(Teacher{Name: "cc"}, "name", "age").Find(&teachers)
}
复合查询
  • 复杂条件查询
var teachers []Teacher
// 复合查询 offset为跳过几个记录,分页会用
DB.Where(DB.Where("name = ?", "yuan").Or("name = ?", "oo")).
Where("age > ?", 40).Order("id desc").Offset(1).Limit(10).Find(&teachers)// 查询返回行rows
rows, err := DB.Model(&Teacher{}).Select("id", "name").Where(DB.Where("name in ?", []string{"oo", "qq"})).
Order("id desc").Offset(1).Limit(10).Rows()if err != nil {log.Fatal(err)
}
defer rows.Close()
// 扫描row
for rows.Next() {id := 0name := ""err = rows.Scan(&id, &name)if err != nil {continue}fmt.Println(id, name)
}
  • 分组聚合
// 分组聚合
type Result struct {Count intAge   int
}
list := []Result{}
DB.Model(&Teacher{}).Select("count(*) as count", "age").Not("name = ?", "yuan").
Group("age").Having("count > ?", 2).Rows()fmt.Println(list)
// 根据年龄分组,过滤掉name为yuan的数据,保留对应分组count数大于2的结果
rows2, err := DB.Model(&Teacher{}).Select("count(*) as count", "age").Not("name = ?", "yuan").
Group("age").Having("count > ?", 2).Rows()
if err != nil {log.Fatal(err)
}
defer rows2.Close()for rows2.Next() {count := 0age := 0err = rows2.Scan(&count, &age)if err != nil {continue}fmt.Println(count, age)
}
使用原生SQL查询

基本exec和raw就够用了

func NativeSql() {var teacher Teachervar list []Teacher//查询DB.Raw("select id,name,age from teachers where name = ?", "yuan").Scan(&teacher)fmt.Println(teacher)DB.Raw("select id,name,age from teachers where name = ?", "yuan").Scan(&list)fmt.Println(list)teacher = Teacher{}DB.Raw("select id,name,age from teachers where name = ?", "yuan").Find(&teacher)fmt.Println(teacher)//更新res := DB.Exec("update teachers set age = @age where name = @name", sql.Named("age", 22), sql.Named("name", "yuan"))fmt.Println(res.RowsAffected, res.Error)}

相关文章:

golang gorm 增删改查以及使用原生SQL(以操作mysql为例)

gorm mysql增删改查 model定义 package _caseimport "gorm.io/gorm"func init() {DB.Migrator().AutoMigrate(Teacher{}, Course{}) } type Roles []stringtype Teacher struct {gorm.ModelName string gorm:"size:256"Email string gorm:&q…...

代码随想录 单调栈part2

503. 下一个更大元素 II 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数…...

详解利用高斯混合模型拆解多模态分布 + 精美可视化

文章目录 一、前言二、主要内容三、总结🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 本文旨在介绍如何利用高斯混合模型(Gaussian Mixture Models,简称 GMMs)将一维多模态分布拆分为多个分布。作为统计 / / /机器学习领域常用的概率模型...

排序算法之【归并排序】

📙作者简介: 清水加冰,目前大二在读,正在学习C/C、Python、操作系统、数据库等。 📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…...

Qt中QTimer定时器的用法

Qt中提供了两种定时器的方式一种是使用Qt中的事件处理函数,另一种就是Qt中的定时器类QTimer。 使用QTimer类,需要创建一个QTimer类对象,然后调用其start()方法开启定时器,此后QTimer对象就会周期性的发出timeout()信号。 1.QTimer…...

vue-组件定义注册使用

vue组件使用的步骤 定义组件注册组件使用组件 定义组件 Vue.extend(options) 其中options和new Vue(options)出入的options对象几乎一样,但是也有不同。 创建 el不用写—最终所有组件需要经过一个vm的管理,由vm的el决定服务哪个容器。 data必须写成函…...

斑馬打印機打印中文

创建项目 首先說一下,本文章是借鉴了其他大佬的文章,然后我记录一下的文章。 首先创建好一个.net framework的winform项目。 这里面主要用到两个库文件: Fnthex32.dll、LabelPrint.dll。 Fnthex32这个有8位参数和9位参数的,我这…...

(一)Apache log4net™ 手册 - 介绍

0、相关概念 Log4j 几乎每个大型应用程序都包含自己的日志记录或跟踪 API。根据这一规则,E.U. SEMPER 🌹项目决定编写自己的跟踪 API。那是在 1996 年初。经过无数次的增强、几个化身和大量的工作,API 已经发展成为 log4j —— 一个流行的 Ja…...

基于Java的民宿管理系统设计与实现(源码+lw+部署文档+讲解等)(民宿预约、民宿预订、民宿管理、酒店预约通用)

文章目录 前言具体实现截图论文参考详细视频演示代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技…...

039:mapboxGL更换地图上的鼠标样式

第039个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中更换地图上的鼠标的样式。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共74行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:htt…...

【云原生】K8S对外服务之Ingress

目录 一、Ingress 简介1.1Ingress 组成1.3Ingress-Nginx 工作原理 二、部署 nginx-ingress-controller2.1部署ingress-controller Pod及相关资源2.2ingress 暴露服务的方式2.3 采用方式二:DaemonSetHostNetworknodeSelector 三、采用方式二:DeploymentNo…...

分布式锁如何实现

分布式是现在的比较主流的技术,常常和微服务一起出现。那么对于多个实例之间,如何证分布式系统中多个进程或线程同步访问共享资源呢?我们其实一想到的就是锁,我们在java里边有 synchronized, 在python里有lock,但是这个…...

Mysql存储-EAV模式

Mysql存储-EAV模式 最近又又又搞一点新东西,要整合不同业务进行存储和查询,一波学习过后总结了一下可扩展性MAX的eav模式存储。 在eav这里的数据结构设计尤为关键,需要充分考虑你需要使用的字段、使用场景,当数据结构设计完成后便…...

全局变量报错:\Output\STM32.axf: Error: L6218E: Undefined symbol

全局变量报错: .\Output\STM32.axf: Error: L6218E: Undefined symbol key_num (referred from main.o). 这里只说全局变量哦,这是因为你在调用的.c文件里 把定义写在了函数里面,写函数外面就没事了 改为: .h的声明文件根本不用写…...

算法错题簿(持续更新)

自用算法错题簿,按算法与数据结构分类 python1、二维矩阵:记忆化搜索dp2、图论:DFS3、回溯:129612964、二叉树:贪心算法5、字符串:记忆化搜索6、01字符串反转:结论题7、二进制数:逆向…...

基于Springboot实现疫情网课管理系统项目【项目源码+论文说明】

基于Springboot实现疫情网课管理系统演示 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于疫情网课管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了疫情…...

Linux文件与目录的增删改查

一、增 1、mkdir命令 作用: 创建一个新目录。 格式: mkdir [选项] 要创建的目录 常用参数: -p:创建目录结构中指定的每一个目录,如果目录不存在则创建,如果目录已存在也不会被覆盖。 用法示例&a…...

JVM的内存模型

一、JVM的内存模型 1.1、目标 内存模型是用来描述JVM内部的内存结构和内存管理的模型。它定义了JVM在运行Java程序时所需要的各种内存区域,以及每个内存区域的作用和特点。 1.2、结构划分 1.2.1、栈 每个线程在执行Java方法时会创建一个栈帧(Stack …...

数据采集项目之业务数据(三)

1. Maxwell框架 开发公司为Zendesk公司开源,用java编写的MySQL变更数据抓取软件。内部是通过监控MySQL的Binlog日志,并将变更数据以JSON格式发送到Kafka等流处理平台。 1.1 MySQL主从复制 主机每次变更数据都会生成对应的Binlog日志,从机可…...

vuedraggable影响点击事件的解决办法

在工作中有很多场景需要针对广告、商品、信息推广等进行一个排序,或者对展示的顺序做出调整,方便放用户第一眼看到自己感兴趣的信息,因此避免不了需要用到排序的插件,这里以vue为例子,采用的插件是vuedraggable,这个插件针对于排序的功能相对完善,官网地址:vuedraggable官网 但…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...