Object Relation Mapping(关系对象映射) 把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中 在具体的操作实体对象的时候,不需要直接与复杂的 SQL语句打交道,只需简单的操作实体对象的属性和方法
表 => struct
列 => struct 属性
行数据 => struct 对象
数据操作 => struct 对象方法的调用/函数的调用
介绍
Gorm是使用go语言开发的ORM库
下载
地址: github.com/jinzhu/gorm
入门
示例
package main
import (
"fmt"
"os"
"time"
_ "github.com/jinzhu/gorm/dialects/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
db.LogMode(true)
// 自动迁移数据库
db.AutoMigrate(&User{})
// 插入数据
for i := 0; i < 10; i++ {
db.Create(&User{Name: fmt.Sprintf("wu_%d", i), Password: "123!@#"})
}
// 按主键获取数据
var u User
db.First(&u, 1)
fmt.Println(u)
// 按条件获取数据
var u2 User
db.First(&u2, "name = ?", "wu_7")
fmt.Println(u2)
// 更新数据
db.Model(u2).Update("password", "!@#QWE")
fmt.Println(u2)
// 删除数据
db.Delete(&u2)
fmt.Println(u2)
}
数据库驱动
MySQL驱动
驱动:github.com/go-sql-driver/mysql
导入:github.com/jinzhu/gorm/dialects/mysql
连接设置 username:password@protocol(host:port)/dbname?charset=utf8mb4&loc=Asia%2FShanghai 为处理Time类型若设置loc为Local, 需要设置parseTime=true
自动迁移
自动迁移数据库到最新版本
只会添加列和索引,不会修改列类型和删除列
示例
package main
import (
"fmt"
"os"
"time"
_ "github.com/jinzhu/gorm/dialects/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
db.LogMode(true)
// 自动迁移数据库
db.AutoMigrate(&User{})
}
判断表是否存在
package main
import (
"fmt"
"os"
"time"
_ "github.com/jinzhu/gorm/dialects/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
// 判断表是否存在
fmt.Println(db.HasTable(&User{}))
// 通过表名判断表是否存在
fmt.Println(db.HasTable("users"))
}
创建表
package main
import (
"fmt"
"os"
"time"
_ "github.com/jinzhu/gorm/dialects/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
db.CreateTable(&User{})
}
删除表
package main
import (
"fmt"
"os"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
// 删除表
db.DropTable(&User{})
// 通过表名删除表
db.DropTable("user")
// 当表不存在时跳过删除
db.DropTableIfExists(&User{})
}
修改列
package main
import (
"fmt"
"os"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
// 修改列的类型
db.Model(&User{}).ModifyColumn("birthday", "datetime")
}
删除列
package main
import (
"fmt"
"os"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
// 删除列
db.Model(&User{}).DropColumn("status")
}
外键
package main
import (
"fmt"
"os"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
gorm.Model
Name string
Password string
Birthday time.Time
Desc string
Status int
}
type Addr struct {
gorm.Model
City string
Street string
UserId uint
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
db.CreateTable(&Addr{})
// 添加外键
db.Model(&Addr{}).AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
}
添加索引
// 添加索引
db.Model(&User{}).AddIndex("idx_birthday", "birthday")
db.Model(&User{}).AddIndex("idx_city_street", "city", "street")
添加唯一索引
// 添加唯一索引
db.Model(&User{}).AddUniqueIndex("idx_name", "name")
db.Model(&User{}).AddUniqueIndex("idx_city_user_id", "city", "user_id")
删除索引
// 删除索引
db.Model(&User{}).RemoveIndex("idx_name")
db.Model(&User{}).RemoveIndex("idx_birthday")
db.Model(&User{}).RemoveIndex("idx_city_street")
db.Model(&User{}).RemoveIndex("idx_city_user_id")
标签
名称:gorm
常用属性
column:设置列名
type:类型
primary_key:主键
AUTO_INCREMENT: 自增长
unique: 唯一
not null: 不允许为NULL
default:默认值
index: 索引
gorm.Model
属性
ID
CreatedAt
UpdatedAt
DeletedAt
方法 func (m Model) TableName() string 设置表名
示例
创建
package main
import (
"fmt"
"os"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
gorm.Model
Name string
Password string `gorm:"default:'123!@#'"` // 设置默认值
}
// 定义回调函数,在创建之前执行
func (u *User) BeforeCreate(scope *gorm.Scope) error {
fmt.Println("before create")
return nil
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
u := User{Name: "wu"}
fmt.Println(db.newRecord(u)) // 判断对象是否已经被创建
db.Create(&u)
fmt.Println(db.newRecord(u))
}
查找
基本查找
package main
import (
"fmt"
"os"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
gorm.Model
Name string
Password string `gorm:"default:'123!@#'"` // 设置默认值
}
func main() {
// 获取数据库连接
db, err := gorm.Open("mysql", "root:1234@tcp(192.168.204.130:3306)/testorm?charset=utf8mb4&parseTime=true&loc=PRC")
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// 延迟关闭数据库连接
defer db.Close()
db.DropTableIfExists("users")
db.AutoMigrate(&User{})
for i := 0; i < 10; i++ {
u := User{Name: fmt.Sprintf("wu_%d", i)}
if err := db.Create(&u).Error; err != nil {
fmt.Println(err)
}
}
// 获取第一条数据
var u01 User
db.First(&u01)
fmt.Println(u01)
// 获取最后一条数据
var u02 User
db.Last(&u02)
fmt.Println(u02)
// 按主键获取
var u03 User
db.First(&u03, 8)
fmt.Println(u03)
// 按条件查询一条
var u04 User
db.First(&u04, "name=?", "wu_5")
fmt.Println(u04)
// 获取所有数据
var us User
db.Find(&us)
fmt.Println(us)
db.Find(&us, "name != ?", "wu_5")
fmt.Println(us)
}
where条件
or条件
查询结果(指定列)
排序(order)
分页(offset&limit)
数量(count)
指定表名
原始SQL
db = db.Table("users").Select("users.name, addresses.city, addresses.street")
rows, _ := db.Joins("left join addresses on users.id = addresses.user_id").Rows()
for rows.Next() {
var name, city, street, string
rows.Scan(&name, &city, &street)
fmt.Println(name, city, street)
}
更新
全部更新
var u User
if err := db.First(&u).Error; err == nil {
u.Name = "wu123"
u.Password = "123!@#"
db.Save(u)
} else {
fmt.Println(err)
}
批量更新
db.Model(&User{}).Where("name like ?", "%3%").Update("password", "123!@#")
// 不会执行Callback更新update_at字段
db.Table("users").Where("name like ?", "%4%").UpdateColumn("password", "123123")
db.Model(&User{}).Where("name like ?", "%5%").UpdateColumn(User{Name: "xxxxxx", Password: "123123"})
// 只会更新指定字段
db.Table("users").Where("name like ?", "%6%").Updates(map[string]interface{}{"password": "xxx", "name": "yyy"})
// 只会更新更改和非零值的字段
db.Model(&User{}).Where("name like ?", "%7%").Updatees(User{Name: "ccc", Password: "aaaa"})
表达式更新
db.Model(&User{}).Update("password", gorm.Expr("md5(password)"))
删除
单记录删除
var u User
if err := db.First(&u).Error; err == nil {
db.Delete(&u)
} else {
fmt.Println(err)
}
批量更新
db.Where("name like ?", "%5%").Delete(User{})
永久更新
db.Unscoped().Where("name like ?", "%6%").Delete(User{})
原始SQL执行
更新
db.Exec
查询
db.Raw(sql).Scan(&rt)
db.Raw(sql).Row()
db.Raw(sql).Rows()
创建
BeforeSave
BeforeCreate
AfterCreate
AfterSave
更新
BeforeSave
BeforeUpdate
AfterUpdate
AfterSave
删除
BeforeDelete
AfterDelete
查找
AfterFind
错误
db.Error
db.GetErrors()
db.RecordNotFound()
日志
db.LogMode(true)
db.Debug().Where()
db.SetLogger()
tx := db.Begin()
tx.Create()
tx.Rollback()
tx.Commit()
todolist
修改todolist使用数据库
登陆
task 增加/删除/修改/查询
object relation mapping
安装mysql
navicat连接数据库
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(127.0.0.1:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
}
orm_test\main.go
package main
import (
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func main() {
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
err = db.AutoMigrate(&model.Product{})
if err != nil {
panic(err)
}
}
orm_test\model\product.go
package model
import "gorm.io/gorm"
type Product struct {
gorm.Model
Code string
Price uint
}
PS D:\Workspace\Go\src\projects\orm_test> go run main.go
连接成功...
2023/05/13 21:32:01 D:/Workspace/Go/src/projects/orm_test/main.go:37
[0.507ms] [rows:-] SELECT DATABASE()
2023/05/13 21:32:01 D:/Workspace/Go/src/projects/orm_test/main.go:37
[3.914ms] [rows:1] SELECT SCHEMA_NAME from Information_schema.SCHEMATA where SCHEMA_NAME LIKE 'orm_test%' ORDER BY SCHEMA_NAME='orm_test' DESC,SCHEMA_NAME limit 1
2023/05/13 21:32:01 D:/Workspace/Go/src/projects/orm_test/main.go:37
[11.688ms] [rows:-] SELECT count(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ? AND table_type = ?
2023/05/13 21:32:01 D:/Workspace/Go/src/projects/orm_test/main.go:37
[68.744ms] [rows:0] CREATE TABLE `products` (`id` bigint unsigned AUTO_INCREMENT,`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,`deleted_at` datetime(3) NULL,`code` longtext,`prince` bigint unsigned,PRIMARY KEY (`id`),INDEX `idx_products_deleted_at` (`deleted_at`))
添加
package main
import (
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
}
func main() {
db.Create(&model.Product{Code: "D42", Price: 200})
}
查找
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
db.First(&p, 1)
fmt.Println(p.Code)
}
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
// db.First(&p, 1)
// fmt.Println(p.Code)
db.First(&p, "code=?", "D42")
fmt.Println(p.Price)
}
更新
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
db.First(&p, "code=?", "D42")
fmt.Println(p.Price)
db.Model(&p).Update("price", 300)
}
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
db.First(&p, 2)
db.Model(&p).Updates(model.Product{
Code: "FF42",
Price: 600,
})
db.First(&p, 2)
fmt.Println(p.Code)
fmt.Println(p.Price)
}
PS D:\Workspace\Go\src\projects\orm_test> go run main.go
连接成功...
2023/05/13 21:58:00 D:/Workspace/Go/src/projects/orm_test/main.go:47
[4.424ms] [rows:0] SELECT * FROM `products` WHERE `products`.`id` = ? AND `products`.`deleted_at` IS NULL ORDER BY `products`.`id` LIMIT 1
2023/05/13 21:58:00 D:/Workspace/Go/src/projects/orm_test/main.go:49 WHERE conditions required
[1.063ms] [rows:0] UPDATE `products` SET `updated_at`=?,`code`=?,`price`=? WHERE `products`.`deleted_at` IS NULL
2023/05/13 21:58:00 D:/Workspace/Go/src/projects/orm_test/main.go:53
[6.741ms] [rows:0] SELECT * FROM `products` WHERE `products`.`id` = ? AND `products`.`deleted_at` IS NULL ORDER BY `products`.`id` LIMIT 1
FF42
600
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
db.First(&p, 2)
// db.Model(&p).Updates(model.Product{
// Code: "FF42",
// Price: 600,
// })
// db.First(&p, 2)
// fmt.Println(p.Code)
// fmt.Println(p.Price)
// 零值 string "" int 0
db.Model(&p).Updates(model.Product{
Code: "FF42",
Price: 0,
})
db.First(&p, 2)
fmt.Println(p.Code)
fmt.Println(p.Price)
}
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
db.First(&p, 2)
db.Model(&p).Updates(map[string]interface{}{
"Code": "",
"Price": 0,
})
db.First(&p, 2)
fmt.Println(p.Code)
fmt.Println(p.Price)
}
删除
func main() {
// db.Create(&model.Product{Code: "D42", Prince: 200})
var p model.Product
db.First(&p, 2)
// delete ... from xxx where id=111 100元->80元
// 软删除 flag status, 0或1 0不显示, 1显示,当删除的时候就把flag字段update为0,查询的时候,选择flag=1的记录
// 商城后台,是有权限查看任何记录,delete_at填充值不为null
db.Delete(&p, 2)
}
D:\Workspace\Go\src\projects\orm_test\model\product.go
package model
import (
"database/sql"
"gorm.io/gorm"
)
type Product struct {
gorm.Model
Code sql.NullString
Price uint
}
D:\Workspace\Go\src\projects\orm_test\main.go
package main
import (
"database/sql"
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
}
func main() {
db.Create(&model.Product{
Code: sql.NullString{String: "D6666", Valid: true},
Price: 8888,
})
}
func main() {
// db.Create(&model.Product{
// Code: sql.NullString{String: "D6666", Valid: true},
// Price: 8888,
// })
var p model.Product
db.First(&p, 3)
fmt.Println(p.Code)
db.Model(&p).Updates(model.Product{
Code: sql.NullString{"", true},
Price: 9999,
})
}
https://gorm.io/zh_CN/docs/models.html
D:\Workspace\Go\src\projects\orm_test\model\product.go
package model
import (
"database/sql"
"gorm.io/gorm"
)
type Product struct {
gorm.Model
Code sql.NullString
Price uint
}
type Food struct {
FoodId uint `gorm:"primarykey"`
Name string `gorm:"column:food_name;type:varchar(32);index:idx_food_name,unique"`
}
package main
import (
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
db.AutoMigrate(&model.Food{})
}
func main() {
}
package main
import (
"database/sql"
"fmt"
"log"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
db.AutoMigrate(&User{})
}
type User struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivatedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
now := time.Now()
u1 := User{Name: "欢喜", Birthday: &now}
result := db.Create(&u1)
fmt.Println(u1.ID)
fmt.Println(result.Error)
fmt.Println(result.RowsAffected)
}
package main
import (
"database/sql"
"fmt"
"log"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
}
type User struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivatedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
db.Model(&User{ID: 2}).Update("Name", "")
}
db.Model(&User{ID: 2}).Updates(User{Name: ""})
s := "[email protected]"
db.Model(&User{ID: 2}).Updates(User{Email: &s})
s := ""
db.Model(&User{ID: 2}).Updates(User{Email: &s})
type User struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivatedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
// 第一种
users := []User{
{Name: "wu123"},
{Name: "ku123"},
{Name: "zu123"},
{Name: "xu123"},
{Name: "lu123"},
}
db.Create(users)
for _, user := range users {
fmt.Println(user.ID)
}
}
func main() {
// 第一种
users := []User{
{Name: "wu123"},
{Name: "ku123"},
{Name: "zu123"},
{Name: "xu123"},
{Name: "lu123"},
}
// 第二种
db.CreateInBatches(users, 2)
for _, user := range users {
fmt.Println(user.ID)
}
}
func main() {
users := []User{
{Name: "wu123"},
{Name: "ku123"},
{Name: "zu123"},
{Name: "xu123"},
{Name: "lu123"},
}
// 第三种
db.Model(User{}).Create([]map[string]interface{}{
{"Name": "wu123"},
{"Name": "ku123"},
{"Name": "zu123"},
{"Name": "xu123"},
{"Name": "lu123"},
})
for _, user := range users {
fmt.Println(user.ID)
}
}
D:\Workspace\Go\src\projects\orm_test\model\model.go
package model
import (
"database/sql"
"time"
)
type User struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivatedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
package main
import (
"errors"
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
}
func main() {
u1 := model.User{}
r := db.First(&u1)
fmt.Println(u1.ID)
fmt.Println(r.Error)
fmt.Println(r.RowsAffected)
b := errors.Is(r.Error, gorm.ErrRecordNotFound)
if b {
fmt.Println("查无此人")
} else {
fmt.Println("他是"+u1.Name)
}
}
func main() {
u2 := model.User{}
db.Take(&u2)
fmt.Println(u2.ID)
}
通过主键查询
func main() {
u3 := model.User{}
r2 := db.First(&u3, 4)
fmt.Println(u3.Name)
fmt.Println(r2)
}
多个主键ID
func main() {
u3 := model.User{}
r2 := db.First(&u3, 2,3,4)
fmt.Println(u3.Name)
fmt.Println(u3.ID)
fmt.Println(r2)
}
func main() {
var users []model.User
r3 := db.Find(&users, []int{2,3,4})
fmt.Println(r3)
for _, user := range users{
fmt.Println(user.Name)
}
}
func main() {
// 主键写错成字符串,还能查询吗?能
u3 := model.User{}
r2 := db.First(&u3, "3")
fmt.Println(u3.Name)
fmt.Println(r2)
}
func main() {
u1 := model.User{}
db.Where("name=?", "wu123").First(&u1)
fmt.Println(u1.ID)
u2 := model.User{}
db.Where(model.User{Name: "wu123"}).First(&u2)
fmt.Println(u2.ID)
}
func main() {
var users []model.User
db.Where("name <> ?", "wu123").Find(&users)
for _, item := range users {
fmt.Println(item.ID)
}
}
func main() {
var userList []model.User
db.Where(map[string]interface{}{"name": "wu123"}).Find(&userList)
for _, item := range userList {
fmt.Println(item.ID)
}
}
func main() {
var userList2 []model.User
db.Where(map[string]interface{}{
"name": "wu123",
"age": 0,
}).Find(&userList2)
for _, item := range userList2 {
fmt.Println(item.ID)
}
}
单列更新
func main() {
// ErrMissingWhereClause
db.Model(&model.User{}).Where("name=?", "wu123").Update("age", 18)
}
u1 := model.User{}
db.First(&u1, 3)
fmt.Println(u1.Name)
db.Model(&u1).Update("email", "[email protected]")
u2 := model.User{}
db.First(&u2, 4)
db.Model(&u2).Where("name=?", "ku123").Update("age", 18)
多列更新
func main() {
u3 := model.User{}
db.First(&u3, 4)
db.Model(&u3).Updates(model.User{Name: "zu123", Age: 17})
}
func main() {
u4 := model.User{}
db.First(&u4, 5)
db.Model(&u4).Updates(map[string]interface{}{
"name": "lu123",
"age": 18,
})
}
func main() {
u5 := model.User{}
db.First(&u5, 5)
db.Model(&u5).Select("name").Updates(map[string]interface{}{
"name": "zzz",
"age": 16,
})
}
func main() {
u6 := model.User{}
db.First(&u6, 7)
db.Model(&u6).Omit("name").Updates(map[string]interface{}{
"name": "zzz",
"age": 16,
})
}
func main() {
u7 := model.User{}
db.First(&u7, 7)
db.Model(&u7).Select("name", "age").Updates(map[string]interface{}{
"name": "zzz",
"age": 0,
})
}
添加商品
func main() {
// delete
// soft delete delete_at
p1 := model.Product{
Code: sql.NullString{
String: "nu123",
Valid: true,
},
Price: 99,
}
p2 := model.Product{
Code: sql.NullString{
String: "ku123",
Valid: true,
},
Price: 99,
}
var productList []model.Product
productList = append(productList, p1)
productList = append(productList, p2)
db.CreateInBatches(productList, 2)
}
func main() {
// delete
// soft delete delete_at
var p model.Product
db.First(&p, 6)
db.Delete(&p)
}
func main() {
// delete
// soft delete delete_at
var p model.Product
db.First(&p, 6)
db.Delete(&p)
db.Where("price=?", 666).Delete(model.Product{})
}
https://gorm.io/zh_CN/docs/delete.html
关联插入
D:\Workspace\Go\src\projects\orm_test\model\model.go
package model
import (
"gorm.io/gorm"
)
type Employer struct {
gorm.Model
Name string
CompanyID int
Company Company
}
type Company struct {
gorm.Model
Name string
}
package main
import (
"database/sql"
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
ab.AutoMigrate(&model.Company{})
ab.AutoMigrate(&model.Employer{})
}
func main() {
// 关联插入,表与表,多个
c1 := model.Company{
Name: "wu123",
}
e1 := model.Employer{
Name: "qu123",
Company: c1,
}
db.Create(&e1)
}
func main() {
var e1 model.Employer
db.First(&e1)
fmt.Println(e1.Name)
fmt.Println(e1.Company.ID)
fmt.Println(e1.Company.Name)
}
func main() {
var e1 model.Employer
db.Preload("Company").First(&e1)
fmt.Println(e1.Name)
fmt.Println(e1.Company.ID)
fmt.Println(e1.Company.Name)
}
func main() {
var e2 model.Employer
db.Joins("Company").First(&e2)
fmt.Println(e2.Name)
fmt.Println(e2.Company.ID)
fmt.Println(e2.Company.Name)
}
var e2 model.Employer
db.Joins("Company").First(&e2, 2)
fmt.Println(e2.Name)
fmt.Println(e2.Company.ID)
fmt.Println(e2.Company.Name)
D:\Workspace\Go\src\projects\orm_test\model\model.go
package model
import (
"gorm.io/gorm"
)
type Employer struct {
gorm.Model
Name string
CompanyID int
Company Company
CreditCards []CreaditCard
}
type Company struct {
gorm.Model
Name string
}
type CreaditCard struct {
gorm.Model
Number string
EmployerId uint
}
package main
import (
"fmt"
"log"
"projects/orm_test/model"
"os"
"time"
"github.com/google/uuid"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
func init() {
var err error
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: true, // Don't include params in the SQL log
Colorful: true, // Disable color
},
)
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "root:1234@tcp(192.168.204.130:3306)/orm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
panic(err)
}
fmt.Println("连接成功...")
db.AutoMigrate(&model.CreaditCard{})
}
func main() {
// has many
var e1 model.Employer
db.First(&e1, 1)
for i := 0; i < 5; i++ {
id := uuid.New()
c := model.CreaditCard{
Number: id.String(),
EmployerId: e1.ID,
}
db.Create(&c)
}
}
func main() {
// has many
var e1 model.Employer
db.First(&e1, 1)
// 第一种模式查询
db.Preload("CreditCards").First(&e1)
for _, card := range e1.CreditCards {
fmt.Println(card.Number)
}
}
func main() {
// has many
// 关联方式查询
var e1 model.Employer
db.First(&e1, 1)
var CreditCards []model.CreditCard
db.Model(&e1).Association("CreditCards").Find(&creditCards)
for _, card := range creditCards {
fmt.Println(card.Number)
}
}