gorm基本操作

一、gorm安装

1.下载gorm

go get -u gorm.io/gorm //gorm框架
go get -u gorm.io/driver/mysql //驱动

2.mysql准备工作

mysql> create database godb;
mysql> grant all on *.* to 'admin'@'%' identified by 'golang123!';
mysql> flush privileges;

3.导入gorm框架

import ("gorm.io/gorm""gorm.io/driver/mysql"
)

4.连接mysql

这里单独创建一个连接mysql的包,

package mysqldbimport ("gorm.io/driver/mysql""gorm.io/gorm"
)func Mysql_connect() *gorm.DB {dsn := "admin:golang123!@tcp(192.168.1.23:3306)/godb?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})return db
}

5.引入连接包函数

package mainimport ("fmt""gorm/mysqldb"
)func main() {db := mysqldb.Mysql_connect()fmt.Println(db)
}

此时如果没有报错,说明连接mysql已经成功了

二、基本使用

1.创建和表对应的结构体

这里新建了一个db.go 也属于mysqldb包

package mysqldbimport "time"//共用结构体,其它结构体直接继承即可,字段是所有表共用字段,所有做一个基础结构体,减少重复定义。
//反撇号中的内容是"标签"。标签的含义结构体转换成另外一种格式的时候,传递过去一些信息
//其实在gorm中有一个自带的gorm.Model结构体,和这里自建的BaseModule 基本一致
type BaseModule struct {Id         int        `gorm:"primarykey"`CreateTime *time.Time `gorm:"autoCreateTime"`UpdateTime *time.Time `gorm:"autoCreateTime"`
}//创建老师表
type Teacher struct {BaseModule        //继承共用结构体,这里使用了匿名字段,使用数据类型(结构体类型)作为字段名称Name       string        `gorm:"type:varchar(32);unique;not null"`Tno        int    //账号Pwd        string //密码Tel        string //电话
}

2.teacher表

在main.go中开始初始Teacher表

package mainimport ("gorm/mysqldb"
)func main() {db := mysqldb.Mysql_connect()//开始初始化表db.AutoMigrate(&mysqldb.Teacher{})
}

查看数据库内容teachers表已经创建好。这里可以看到 BaseModel 不用初始化为数据库表。teacher表中也会继承了它的字段

mysql> use godb
Database changed
mysql> show tables;
+----------------+
| Tables_in_godb |
+----------------+
| teachers       |
+----------------+
1 row in set (0.00 sec)mysql> desc teachers;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| create_time | datetime(3) | YES  |     | NULL    |                |
| update_time | datetime(3) | YES  |     | NULL    |                |
| name        | varchar(32) | NO   | UNI | NULL    |                |
| tno         | bigint(20)  | YES  |     | NULL    |                |
| pwd         | longtext    | YES  |     | NULL    |                |
| tel         | longtext    | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

2.1 手动插入数据

这里手动插入数据。ID列是自增长列,在手动插入数据的时候写NULL就可以了。两个时间字段用now()函数就可以了

mysql>insert into  teachers values(NULL,now(),now(),"teacher wang",3123,"wang!","13312312311");
mysql> select * from teachers;
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
| id | create_time             | update_time             | name         | tno  | pwd   | tel         |
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
|  1 | 2023-07-20 22:37:20.000 | 2023-07-20 22:37:20.000 | teacher wang | 3123 | wang! | 13312312311 |
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
1 row in set (0.00 sec)

2.2 在次初始化

go run main.go

此时发现数据没有受到任何影响。
但是会重复生成: UNIQUE KEY. 通过show create table 表名查看

2.3 表名变复数

结构体的名称为teacher 但是创建的表变成了teachers 多了一个s 这是在迁移过程中库自己加的。如果不影响使用可以忽略。

3.class表

class表对应结构体如下

type Class struct {BaseModuleName string `gorm:"type:varchar(32);unique;not null"`Num  intTId  intT    Teacher
}

注意:

TId  int 
这个字段是外键字段,字段的值指向 teacher表的 id 字段值
T    Teacher
这个成员变量不会在mysql中产生字段。这是设置的 TId字段的 外键关联语句,相当于 foreign key 字段名 refences 主表(id)1.T的意思是:gorm会根据这个名字(T)自动在后边加上Id,然后在结构体中找这个变量,并且将这个字段设置为外键。 也就是说 T = TId. 如果你的外键字段在命名时,那将设置外键关联失败
2.Teacher的意思是: 它是Teacher表, gorm在管理的时候 会自动关联到Teacher的ID字段这中简写方式是gorm 提供的语法糖

1.开始迁移

package mainimport ("gorm/mysqldb"
)func main() {db := mysqldb.Mysql_connect()db.AutoMigrate(&mysqldb.Class{})}

2.查看表

mysql> show tables;
+----------------+
| Tables_in_godb |
+----------------+
| classes        |
| teachers       |
+----------------+
2 rows in set (0.00 sec)mysql> desc classes;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| create_time | datetime(3) | YES  |     | NULL    |                |
| update_time | datetime(3) | YES  |     | NULL    |                |
| name        | varchar(32) | NO   | UNI | NULL    |                |
| num         | bigint(20)  | YES  |     | NULL    |                |
| t_id        | bigint(20)  | YES  | MUL | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)mysql> show create table classes;| classes | CREATE TABLE `classes` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`create_time` datetime(3) DEFAULT NULL,`update_time` datetime(3) DEFAULT NULL,`name` varchar(32) NOT NULL,`num` bigint(20) DEFAULT NULL,`t_id` bigint(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`),KEY `fk_classes_t` (`t_id`),//这里已经创建好了外键关联CONSTRAINT `fk_classes_t` FOREIGN KEY (`t_id`) REFERENCES `teachers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

三、新增数据

1.Teacher表新增数据

package mainimport ("gorm/mysqldb""gorm.io/gorm"
)func Insert(db *gorm.DB) {t1 := mysqldb.Teacher{Name: "wang", Tno: 1, Pwd: "123!", Tel: "11012341235"}db.Create(&t1)
}func main() {db := mysqldb.Mysql_connect()Insert(db)}

1.1.注意事项1

t1 := mysqldb.Teacher{Name: "wang", Tno: 1, Pwd: "123!", Tel: "11012341235"}
实例化的时候使用键值对的方式赋值,不要使用{"wang",1,"123!","11012341235"}这种方式,因为我们继承了BaseModule

1.2.注意事项2

db.Create(&t1)
在新增数据的时候,一定要传入结构体实例的指针,因为gorm要把主键值回写到结构体实例

1.3 新增结果

这里可以看到,在新增的的时候,没有新增BaseModule的数据,但是在数据里自动生成了。并且ID是自增长的

mysql> select * from teachers;
+----+-------------------------+-------------------------+------+------+------+-------------+
| id | create_time             | update_time             | name | tno  | pwd  | tel         |
+----+-------------------------+-------------------------+------+------+------+-------------+
|  1 | 2023-08-03 10:21:03.551 | 2023-08-03 10:21:03.551 | wang |    1 | 123! | 11012341235 |
+----+-------------------------+-------------------------+------+------+------+-------------+
1 row in set (0.00 sec)

2.Class新增数据

func InsertClass(db *gorm.DB) {c1 := mysqldb.Class{Name: "python", Num: 30, TId: 1}db.Create(&c1)}

插入数据如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
1 row in set (0.00 sec)

2.1 插入多条数据

func InsertClass(db *gorm.DB) {c2 := mysqldb.Class{Name: "java", Num: 30, TId: 1}c3 := mysqldb.Class{Name: "go", Num: 30, TId: 1}c4 := mysqldb.Class{Name: "shell", Num: 30, TId: 1}class_list := []mysqldb.Class{c2, c3, c4}db.Create(&class_list)}

插入数据如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | go     |   30 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+

四、单表查询

1.查询全部 db.Find()

func selectdata(db *gorm.DB) {// 这里定义切片的含义:// 1. 因为返回是多条数据,所以定义Class类型切片// 2. db.find函数是根据这里result的类型来判定去库里查找对应的哪张表var result []mysqldb.Class// 将查询结果集回写到result切片当中db.Find(&result)for i, v := range result {fmt.Println("i = ", i)fmt.Println("v = ", v.Name)}
}

执行结果如下:

E:\code\project\后端项目\go_project\gin框架学习>go run main.go
i =  0
v =  python
i =  1
v =  java
i =  2
v =  go
i =  3
v =  shell

2.查询单条

func selectdata(db *gorm.DB) {//三个变量设置的都是结构体实例,不是切片,因为查询结果是一条。var result mysqldb.Classvar result1 mysqldb.Classvar result2 mysqldb.Classdb.Take(&result)     //获取第一条记录,没有指定排序字段db.First(&result1)  //获取第一条记录(主键升序)db.Last(&result2)   //获取最后一条记录,主键降序fmt.Println("result = ", result)fmt.Println("result1 = ", result1)fmt.Println("result2 = ", result2)}

3.where查询

注意: where条件查询的时候,条件参数不能直接写,必须使用? 然后在将参数传递给?

3.1.等值查询

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Where("Name = ?", "java").Find(&result)fmt.Println("result = ", result)
}

3.2 大于查询

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Where("update_time > ?", "2023-08-08 13:40:00").Find(&result)fmt.Println("result = ", result)
}

3.3 and

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Where("num = ? and name = ?", 30, "go").Find(&result)fmt.Println("result = ", result)
}

4. db.select

查询结果返回部分字段,而不是全部字段.

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Select("Name,num").Where("num = ? and name = ?", 30, "go").Find(&result)fmt.Println("result = ", result)
}

这里只返回了Name和Num两个字段,其他字段内容没有进行回写

5.db.Omit

除了Name和Num字段 其他的字段其全部返回

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Omit("Name,Num").Where("num = ? and name = ?", 30, "go").Find(&result)fmt.Println("result = ", result)
}

五、更新

数据库数据如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | go     |   30 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+

1.修改单个字段

将go 改为golang
这里的db.Model 是用来指定表对应的结构体。

func update_data(db *gorm.DB) {db.Model(&mysqldb.Class{}).Where("id = ?", 3).Update("name", "golang")
}

修改成功

mysql> select * from classes where id = 3;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | golang |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
1 row in set (0.00 sec)

2.修改多个字段

注意这里用的是updates,上边用的是update

func update_data(db *gorm.DB) {db.Model(&mysqldb.Class{}).Where("id = ?", 3).Updates(mysqldb.Class{Name: "c++", Num: 20})}

修改成功

mysql> select * from classes where id = 3;
+----+-------------------------+-------------------------+------+------+------+
| id | create_time             | update_time             | name | num  | t_id |
+----+-------------------------+-------------------------+------+------+------+
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | c++  |   20 |    1 |
+----+-------------------------+-------------------------+------+------+------+
1 row in set (0.00 sec)

3.更新表达式gorm.Expr

func update_data(db *gorm.DB) {db.Model(&mysqldb.Class{}).Where("id = ?", 3).Update("num", gorm.Expr("num + 1"))}

更改结果如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | c++    |   21 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
4 rows in set (0.00 sec)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/32483.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4-20mA模拟电流回路协议比0-20mA模拟电流回路协议有什么优势?

有很多原因使得我们采用4-20mA电流回路协议作为事实标准(特别针对回路供电的设备,比如二线制传感器)。其中最重要的有以下两点: 1)在一个直流系统中,能够有效地侦测开路状态。如果在4-20mA系统中&#xff0…

Unity学习笔记--如何优雅简便地利用对象池生成游戏对象(进阶版)LRU + 对象池

前言 之前写过一篇关于对象池的文章,现在来看写的并不是很好,所以来考虑优化下。 现在来看一年前写的代码,越看越不能入目hhh Unity学习笔记–如何优雅简便地利用对象池生成游戏对象 前置知识 Unity学习笔记–使用 C# 开发一个 LRU 代码实…

Camunda 7.x 系列【7】Spring Boot 集成 Camunda 7.19

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. Camunda Platform Run3. Spring Boot 版本兼容性4. 集成 Spring Boot5. 启动项目…

暑假集训笔记

Problem - B - Codeforces 这题看了好久,一直没思路..也可能是早上来没睡醒的原因吧.有点困.. 昨天晚上12点睡的,然后早上直接睡到7.48....真的6啊 话说这题真有点猜的成分, 先说我的思路:一开始和的奇偶 如果为偶数&#xf…

构建 LVS-DR 群集、配置nginx负载均衡。

目录 一、基于 CentOS 7 构建 LVS-DR 群集 1、准备四台虚拟机 2、配置负载调度器(192.168.2.130) 3、部署共享存储(192.168.2.133) 4、配置两个Web服务器(192.168.2.131、192.168.2.132) 测试集群 二…

Location匹配与Rewrite重写

一、常见的Nginx正则表达式 ^ :匹配输入字符串的起始位置 $ :匹配输入字符串的结束位置 * :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”:匹配前面的字符一次或多次。如“ol”能匹配“ol”及“oll”、“oll…

jQuery练习题

目录 1.制作QQ简易聊天框 2.制作课工场论坛发帖 1.制作QQ简易聊天框 <script>$(function () {var touxiang new Array("images/head01.jpg","images/head02.jpg","images/head03.jpg");var names new Array("时尚伊人", &qu…

nvidia驱动更新导致驱动版本不匹配

关于nvidia驱动自动更新&#xff1a; 和这篇描述类似&#xff1a;https://blog.csdn.net/weixin_43568307/article/details/128187469 记得记录原先版本 sudo dpkg-reconfigure unattended-upgrades 关闭一下自动更新。 当前主机做好快照备份&#xff0c;重新安装之前的驱…

Django路由Router

文章目录 一、路由router路由匹配命名空间反向解析 二、实践创建用户模型Model添加子路由 - 创建用户首页页面跳转 - 使用反向解析和命名空间1. 不使用命名空间的效果2. 使用命名空间的效果 用户详情页面跳转 - 路由传参路由传递多个参数re_path 以前写法,了解即可重定向Redire…

全景图!最近20年,自然语言处理领域的发展

夕小瑶科技说 原创 作者 | 小戏、Python 最近这几年&#xff0c;大家一起共同经历了 NLP&#xff08;写一下全称&#xff0c;Natural Language Processing&#xff09; 这一领域井喷式的发展&#xff0c;从 Word2Vec 到大量使用 RNN、LSTM&#xff0c;从 seq2seq 再到 Attenti…

Cocos Creator的rigidBody.applyForce变成了滚动

序: 1、原因是因为没有调整摩擦系数physics-material 2、摩擦系数调整你要在你的节点 一个物理材料才会有的&#xff0c;教程没跳过去了所以没有 3、扩展阅读第一话&#xff1a;入行程序员的一波三折 最终效果&#xff1a; git录屏会卡&#xff0c;其实过程很平滑 正…

vue项目切换页面白屏不显示解决方案

问题描述 1、页面切换后白屏&#xff0c;同时切换回上一个页面同样白屏 2、刷新后正常显示 3、有警告&#xff1a;Component inside <Transition> renders non-element root node that cannot be animated 解决方法 <Transition>中的组件呈现不能动画化的非元素…

安卓如何快速定位native内存泄露。

步骤1&#xff09;cat /proc/pid/status,观察下面俩个指标 RssAnon: 5300 kB //一直增大说明匿名映射的内存增大&#xff0c;malloc本质就是调用匿名映射分 配内存 RssFile: 26884 kB //文件句柄泄露&#…

mysql之存储过程

目录 一、mysql之存储过程的相关知识 1&#xff09;存储过程的概念 2&#xff09;存储过程的优点 二、存储过程的管理 1&#xff09;创建存储过程 基本格式&#xff1a; 2&#xff09;调用存储过程 格式&#xff1a; call 存储过程名称 3&#xff09;查看存储过程 查…

TVS二极管失效分析

摘要&#xff1a;常用电路保护器件的主要失效模式为短路&#xff0c;瞬变电压抑制器(TvS)亦不例外。TvS 一旦发生短路失效&#xff0c;释放出的高能量常常会将保护的电子设备损坏&#xff0e;这是 TvS 生产厂家和使用方都想极力减少或避免的情况。通过对 TVS 筛选和使用短路失效…

【MFC】11.MFC文档和单文档架构-笔记

MFC文档 之前我们在写字符雨的时候&#xff0c;将数据都存储到了视图类中&#xff0c;这是不合理的&#xff0c;视图类只负责显示&#xff0c;不应该存储任何数据 文档&#xff1a;专门存储数据用的 CDocument 文档与视图的关系&#xff1a; 创建一个文档类 单文档四个类都…

浅谈JavaScript编程过程function函数的几种编程风格

作者来源&#xff1a;https://ost.51cto.com/user/posts/16066420 声明 JavaScript编程过程中函数是一个很有趣的点&#xff0c;JavaScript的函数与其他如:C、Java等语言有很大区别。对于从别的编程语言转来的同学可能会存在一定的“坑”&#xff0c;如function函数与>函数…

vue3 vite gzip

1、首先前端项目里安装 vite-plugin-compression 插件 yarn add vite-plugin-compression 2、在 vite.config.js 中 import vue from vitejs/plugin-vue import { defineConfig } from vite import compressPlugin from vite-plugin-compressionexport default defineConf…

C语言 指针的运算

目录 一、介绍 二、指针 整数 、指针 - 整数 二、指针 - 指针 四、指针的关系运算 一、介绍 在C语言中&#xff0c;指针的运算分为三类 1、指针 整数 、指针 - 整数2、指针 - 指针3、指针的关系运算 二、指针 整数 、指针 - 整数 因为数组在…

桂林小程序https证书

现在很多APP都相继推出了小程序&#xff0c;比如微信小程序、百度小程序等&#xff0c;这些小程序的功能也越来越复杂&#xff0c;不可避免的和网站一样会传输数据&#xff0c;因此小程序想要上线就要保证信息传输的安全性&#xff0c;也就是说各种类型的小程序也需要部署https…