go 学习之gorm
gorm是一个饱受好评的orm框架,此处数据库我们以mysql为例
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
) var db *gorm.DB
func init() {
var err error
db, err = gorm.Open("mysql", "<user>:<password>/<database>?charset=utf8&parseTime=True&loc=Local")#非常简便就创建了一个数据库连接
if err != nil {
panic(err)
}
}
光创建连接还不够,我们还需要model
type User struct {
gorm.Model
Name string
Age sql.NullInt64 # import "dataase/sql"
Birthday *time.Time # import time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"` // 设置字段大小为255
MemberNumber *string `gorm:"unique;not null"` // 设置会员号(member number)唯一并且不为空
Num int `gorm:"AUTO_INCREMENT"` // 设置 num 为自增类型
Address string `gorm:"index:addr"` // 给address字段创建名为addr的索引
IgnoreMe int `gorm:"-"` // 忽略本字段
}
#这个结构体就对应我们的数据库表
下一步我们就开始迁移数据库
方法一 手动创建表:
if !db.HasTable(&User{}) {
db.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8").CreateTable(&User{})
} 方法二 自动迁移命令:
db.AutoMigrate(&User{})
//注意:自动迁移 只会 创建表、缺失的列、缺失的索引, 不会 更改现有列的类型或删除未使用的列,以此来保护您的数据。
//也就是说我们修改user结构体 注销age属性,添加一个sex属性,自动迁移后,表结构还是存在age字段,添加sex字段
然后我们来简单说说增删改查
#增
user := User{Name: "Jinzhu",Sex:"", Age: 18}
db.Create(&user)
#查询
var user [] User
// 获取第一条记录,按主键排序
db.First(&user)
//// SELECT * FROM users ORDER BY id LIMIT 1; // 获取最后一条记录,按主键排序
db.Last(&user)
//// SELECT * FROM users ORDER BY id DESC LIMIT 1; // 获取所有记录
db.Find(&users)
//// SELECT * FROM users; // 使用主键获取记录
db.First(&user, 10)
//// SELECT * FROM users WHERE id = 10;
Where查询条件 (简单SQL)
// 获取第一个匹配记录
db.Where("name = ?", "jinzhu").First(&user)
//// SELECT * FROM users WHERE name = 'jinzhu' limit 1; // 获取所有匹配记录
db.Where("name = ?", "jinzhu").Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu'; db.Where("name <> ?", "jinzhu").Find(&users) // IN
db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users) // LIKE
db.Where("name LIKE ?", "%jin%").Find(&users) // AND
db.Where("name = ? AND age >= ?", "jinzhu", "").Find(&users) // Time
db.Where("updated_at > ?", lastWeek).Find(&users) db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
Where查询条件 (Struct & Map)
注意:当使用struct查询时,GORM将只查询那些具有值的字段 // Struct
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1; // Map
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20; // 主键的Slice
db.Where([]int64{20, 21, 22}).Find(&users)
//// SELECT * FROM users WHERE id IN (20, 21, 22);
1.2.3. Not条件查询
db.Not("name", "jinzhu").First(&user)
//// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1; // Not In
db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)
//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2"); // Not In slice of primary keys
db.Not([]int64{1,2,3}).First(&user)
//// SELECT * FROM users WHERE id NOT IN (1,2,3); db.Not([]int64{}).First(&user)
//// SELECT * FROM users; // Plain SQL
db.Not("name = ?", "jinzhu").First(&user)
//// SELECT * FROM users WHERE NOT(name = "jinzhu"); // Struct
db.Not(User{Name: "jinzhu"}).First(&user)
//// SELECT * FROM users WHERE name <> "jinzhu"; #user为查询的结果数组 删除操作
// 删除存在的记录
db.Delete(&email)
//// DELETE from emails where id=10; // 为Delete语句添加额外的SQL选项
db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)
//// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);
批量删除
删除所有匹配记录 db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
//// DELETE from emails where email LIKE "%jinhu%"; db.Delete(Email{}, "email LIKE ?", "%jinzhu%")
//// DELETE from emails where email LIKE "%jinhu%";
软删除
如果模型有DeletedAt字段,它将自动获得软删除功能! 那么在调用Delete时不会从数据库中永久删除,而是只将字段DeletedAt的值设置为当前时间。 db.Delete(&user)
//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111; // 批量删除
db.Where("age = ?", 20).Delete(&User{})
//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20; // 软删除的记录将在查询时被忽略
db.Where("age = 20").Find(&user)
//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL; // 使用Unscoped查找软删除的记录
db.Unscoped().Where("age = 20").Find(&users)
//// SELECT * FROM users WHERE age = 20; // 使用Unscoped永久删除记录
db.Unscoped().Delete(&order)
//// DELETE FROM orders WHERE id=10; 更新操作
更新全部字段
Save将包括执行更新SQL时的所有字段,即使它没有更改 db.First(&user) user.Name = "jinzhu 2"
user.Age = 100
db.Save(&user) //// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
更新更改字段
如果只想更新更改的字段,可以使用Update, Updates 更新单个属性(如果更改)
db.Model(&user).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; // 使用组合条件更新单个属性
db.Model(&user).Where("active = ?", true).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true; // 使用`map`更新多个属性,只会更新这些更改的字段
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111; // 使用`struct`更新多个属性,只会更新这些更改的和非空白字段
db.Model(&user).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111; // 警告:当使用struct更新时,FORM将仅更新具有非空值的字段
// 对于下面的更新,什么都不会更新为"",0,false是其类型的空白值
db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
更新选择的字段
如果您只想在更新时更新或忽略某些字段,可以使用Select, Omit db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//// UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
更新更改字段但不进行Callbacks
以上更新操作将执行模型的BeforeUpdate, AfterUpdate方法,更新其UpdatedAt时间戳,在更新时保存它的Associations,如果不想调用它们,可以使用UpdateColumn, UpdateColumns // 更新单个属性,类似于`Update`
db.Model(&user).UpdateColumn("name", "hello")
//// UPDATE users SET name='hello' WHERE id = 111; // 更新多个属性,与“更新”类似
db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18 WHERE id = 111;
Batch Updates 批量更新
Callbacks在批量更新时不会运行 db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})
//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11); // 使用struct更新仅适用于非零值,或使用map[string]interface{}
db.Model(User{}).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18; // 使用`RowsAffected`获取更新记录计数
db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
go 学习之gorm的更多相关文章
- Go orm框架gorm学习
之前咱们学习过原生的Go连接MYSQL的方法,使用Go自带的"database/sql"数据库连接api,"github.com/go-sql-driver/mysql& ...
- Go组件学习——gorm四步带你搞定DB增删改查
1.简介 ORM Object-Relationl Mapping, 它的作用是映射数据库和对象之间的关系,方便我们在实现数据库操作的时候不用去写复杂的sql语句,把对数据库的操作上升到对于对象的操作 ...
- Casbin + Gin + Gorm 学习探索
Casbin 是一个强大的,开源的访问控制框架,权限管理机制支持多种访问控制模型: 并且支持多种编程语言: 文档地址:https://casbin.org/docs/zh-CN/overview Gi ...
- gorm学习地址
1 gorm curd指南 2 gorm入门指南
- GORM学习指南
orm是一个使用Go语言编写的ORM框架.它文档齐全,对开发者友好,支持主流数据库. 一.初识Gorm Github GORM 中文官方网站内含十分齐全的中文文档,有了它你甚至不需要再继续向下阅读本文 ...
- Golang 学习笔记 目录总结
- 基础: 下载安装 声明变量的方法 数据的三种基础类型:bool,数字,string 数据类型:数组和切片 数据类型:Maps 条件判断以及循环 函数 包管理 package 指针 结构体 - 初步 ...
- 19.10.11学习日记随笔 mysql事务隔离性
一天的感悟 学习事务的处理方式,其中反想自己学过的flask 默认是开启事务的,flask_sqlalchemy每次在提交时都是需要commit,或者失败是需要rollback回滚操作的,其实pyth ...
- 从别人的代码中学习golang系列--01
自己最近在思考一个问题,如何让自己的代码质量逐渐提高,于是想到整理这个系列,通过阅读别人的代码,从别人的代码中学习,来逐渐提高自己的代码质量.本篇是这个系列的第一篇,我也不知道自己会写多少篇,但是希望 ...
- 如何使用 Gin 和 Gorm 搭建一个简单的 API 服务 (一)
介绍 Go 语言最近十分火热,但对于新手来说,想立马上手全新的语法和各种各样的框架还是有点难度的.即使是基础学习也很有挺有挑战性. 在这篇文章中,我想用最少的代码写出一个可用的 API 服务. ...
随机推荐
- npm run dev 报错:Error: Cannot find module 'webpack-cli/bin/config-yargs'
使用 npm run dev 时报错: Error: Cannot find module 'webpack-cli/bin/config-yargs' 原因是找不到webpack-cli这个包,使用 ...
- textarea实现高度自适应
css部分 #textarea { display: block; margin:0 auto; overflow: hidden; width: 550px; font-size: 14px; he ...
- kali Linux 入门(一)
一.描述 1.基于Debian Linux 发行版 2013年3月13日 2.包含约600个安全工具 3.定制 安全稳定的内核 4.前身是BackTrack(2013年停止维护) 5.官方机构:Off ...
- (ACM模板)集合set
#include<iostream> #include<cstdio> #include<set> using namespace std; int main() ...
- AbstractQueuedSynchronizer简单使用
AQS是JUC中很多同步组件的构建基础,简单来讲,它内部实现主要是状态变量state和一个FIFO队列来完成,同步队列的头结点是当前获取到同步状态的结点,获取同步状态state失败的线程,会被构造成一 ...
- MongoDB 导入导出以及数据库备份
-------------------MongoDB数据导入与导出------------------- 1.导出工具:mongoexport 1.1.概念: mongoDB中的 ...
- List接口和Set接口及其常用实现类概述
一.List接口 List:有序的 collection(也称为序列).此接口的用户可以对列表中每个元素的插入位置进行精确地控制.用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元 ...
- Redis GeoHash
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11632810.html 背景 微信找附近的人,滴滴找附近的单车,饿了么找附近的餐馆 GeoHash算法 ...
- onkeyup的使用(将输入值为非数字的字符替换为空)
onkeyup:当输入值的键盘抬起时触发这个事件. 例如: onkeyup="this.value=this.value.replace(/\D/g,'') 这是个正则式验证,用来验证输入值 ...
- 【leetcode】1014. Capacity To Ship Packages Within D Days
题目如下: A conveyor belt has packages that must be shipped from one port to another within D days. The ...