Go语言基础之GORM框架入门

186 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天

GORM入门

一、DSN和ORM介绍

1.什么是DSN

dsn的全称是Data Source Name ,即数据来源名称,是一个表示ODBC连接的名称。连接到ODBC时,它会存储连接的详细信息,例如数据库名称、目录、数据库驱动程序、用户ID、密码等。

//mysql dsn格式
//涉及参数:
//username   数据库账号
//password   数据库密码
//host       数据库连接地址,可以是Ip或者域名
//port       数据库端口
//Dbname     数据库名
username:password@tcp(host:port)/Dbname?charset=utf8&parseTime=True&loc=Local
​
//示例
//utf8mb4可支持完整的UTF-8编码
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

2.什么是ORM

orm的全称是object relational mapping,即对象映射关系程序,通过ORM将编程语言的对象模型和数据库的关系模型建立映射关系,,让程序猿不在直接用sql语句,而是使用编程语言的对象模型进行数据库操作(在go语言中即gorm提供的接口),保证了一致性的使用习惯。

二、GORM的特点

  • 全功能 ORM
  • 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
  • Create,Save,Update,Delete,Find 中钩子方法
  • 支持 PreloadJoins 的预加载
  • 事务,嵌套事务,Save Point,Rollback To Saved Point
  • Context、预编译模式、DryRun 模式
  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
  • SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
  • 复合主键,索引,约束
  • Auto Migration
  • 自定义 Logger
  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
  • 每个特性都经过了测试的重重考验
  • 开发者友好

三、最简单的MySQL连接

1.gorm配置

# 导入gorm包
go get -u gorm.io/gorm
# mysql驱动 
go get -u gorm.io/driver/mysql
# sqlite 驱动
go get -u gorm.io/driver/sqlite
​

2.gorm连接mysql代码

package main
​
import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)
​
func main() {
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

image-20230202112050579

四、创建表

package main
​
import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)
​
type User struct {
    // gorm:"primary_key" 主键
    Id       int64  `json:"id" gorm:"primary_key"`
    Username string `json:"username" gorm:"username"`
    Password string `json:"password" gorm:"password"`
}
​
func main() {
    dsn := "root:tzx131359@tcp(127.0.0.1:3306)/hospital?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
​
    if err != nil {
        panic(err)
    }
    
    //表创建的接口
    db.AutoMigrate(User{})
}
​

运行完程序后,我们就可以登录我们的mysql去验证程序是否创建成功

image-20230202114810050

在hosptial数据库中,我们看到新增了users表,所以程序是正确的

image-20230202114928965

五、CRUD接口

1.增加-create接口

通过数据的指针来创建

    db.Create(&User{
        Username: "test",
        Password: "123456",
    })

运行程序后,到mysql查看结果

image-20230202115347189

2.查询

官方中文文档的解释:

// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
​
​
//根据主键检索
db.First(&user, 10)
// SELECT * FROM users WHERE id = 10;
​
db.First(&user, "10")
// SELECT * FROM users WHERE id = 10;
​
db.Find(&users, []int{1,2,3})
// SELECT * FROM users WHERE id IN (1,2,3);
​
​
//条件检索
// Get first matched record
db.Where("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;// Get all matched records
db.Where("name <> ?", "jinzhu").Find(&users)
// SELECT * FROM users WHERE name <> 'jinzhu';// IN
db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users)
// SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');// LIKE
db.Where("name LIKE ?", "%jin%").Find(&users)
// SELECT * FROM users WHERE name LIKE '%jin%';// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;// Time
db.Where("updated_at > ?", lastWeek).Find(&users)
// SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
// SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';
​
​
//内联查询
// Get by primary key if it were a non-integer type
db.First(&user, "id = ?", "string_primary_key")
// SELECT * FROM users WHERE id = 'string_primary_key';// Plain SQL
db.Find(&user, "name = ?", "jinzhu")
// SELECT * FROM users WHERE name = "jinzhu";
​
db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20)
// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;// Struct
db.Find(&users, User{Age: 20})
// SELECT * FROM users WHERE age = 20;// Map
db.Find(&users, map[string]interface{}{"age": 20})
// SELECT * FROM users WHERE age = 20;
​
​

示例代码

    //db.AutoMigrate(User{})
​
    db.Create(&User{
        Username: "li",
        Password: "123456",
    })
​
    /*db.Model(User{
        Id: 1,
    }).Update("Password", "456789")*/
​
    //查询单条数据
    u := User{Id: 2}
    db.First(&u)
    fmt.Printf("%#v\n", u)
​
    //查询所有数据
    users := []User{}
    db.Find(&users)
    fmt.Printf("%#v\n", users)

查询结果:

image-20230202121553553

3.修改-update接口

    db.Model(User{
        Id: 1,
    }).Update("Password", "456789")

查询到id为1的数据,并将其的Password进行修改

image-20230202115911754

4.删除-delete接口

    users := []User{}
    db.Delete(&User{Id: 1})
    db.Find(&users)
    fmt.Printf("%#v\n", users)
    // 条件删除
    db.Where("Username = ?", "li").Delete(&User{})
    db.Find(&users)
    fmt.Printf("%#v\n", users)
​

程勋运行结果

image-20230202122506644

官方文档连接

GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.