使用GORM框架连接数据库实现增删改查 | 青训营

80 阅读5分钟

GORM简介

一、GORM

GORM是Go语言的一个使用Go语言实现的且功能非常完善的易使用的ORM框架。

ORM

ORM(Object Relational Mapping),对象关系映射,可以简单理解为将关系型数据库中的数据表映射为编程语言中的具体的数据类型(如struct)。

二、为什么选择GORM

  • 全功能ORM
  • 关联 (Has One, Has Many, Belongs To, Many To Many, 多态)
  • Create,Save,Update,Delete,Find中钩子方法 (在创建/保存/更新/删除/查找之前或之后)
  • 预加载(支持Preload和Joins)
  • 事务,嵌套事务
  • 复合主键
  • SQL构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
  • 数据库自动迁移 Auto Migration
  • 自定义日志
  • 可扩展性, 可基于 GORM 回调编写插件

三、GORM使用

  • 安装:GORM官方支持的数据库类型有,MySQL,PostgreSQL,SQlite,SQL Server
## 安装
gorm go get -u gorm.io/gorm 
## 安装相应的数据库驱动。GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server 
go get -u gorm.io/driver/mysql
  • 连接到数据库(MySQL为例)
package main

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

func main() {
    // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
    //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{})
    db, err := gorm.Open(mysql.New(mysql.Config{
        DSN:                       "root:123456@tcp(192.168.168.101:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
        DefaultStringSize:         256,              // string 类型字段的默认长度
        DisableDatetimePrecision:  true,              // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
        DontSupportRenameIndex:    true,              // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
        DontSupportRenameColumn:   true,              // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
        SkipInitializeWithVersion: false,              // 根据当前 MySQL 版本自动配置
    }), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    // ----------------------------数据库连接池----------------------------
    sqlDB, err := db.DB()
    // SetMaxIdleConns 设置空闲连接池中连接的最大数量
    sqlDB.SetMaxIdleConns(10)
    // SetMaxOpenConns 设置打开数据库连接的最大数量。
    sqlDB.SetMaxOpenConns(100)
    // SetConnMaxLifetime 设置了连接可复用的最大时间。
    sqlDB.SetConnMaxLifetime(time.Hour)
    fmt.Println("success to link mysql")
    select {}
}

基本操作:

使用gorm.Open()函数返回一个gorm.DB结构体后,我们可以使用gorm.DB结构体提供的方法操作数据库,下面我们演示如何使用gorm.DB进行创建、查询、更新、删除等最基本的操作。

其实gorm.DB是在Go语言的database/sql库中的sql.DB结构体上再封装,因为gorm.DB提供许多和sql.DB一样的方法,如下所示:

func (s *DB) Exec(sql string, values ...interface{}) *DB
func (s *DB) Row() *sql.Row
func (s *DB) Rows() (*sql.Rows, error)
func (s *DB) Scan(dest interface{}) *DB

另外,使用gorm.DB结构体中的DB()方法,可以返回一个sql.DB对象,如下:

func (s *DB) DB() *sql.DB

下面演示的是使用gorm.DB结构体中一些更简便的方法进行数据库基本操作。在演示之前需要定义一个模型:

type User struct{
    Id int //对应数据表的自增ID
    Username string
    Password string
    Email string
    Phone string
}

定义了一个名称为User的结构体,gorm支持将结构体按规则映射为某个数据表的一行,结构体的每个字段表示数据表的列,结构体的字段首字母必须大写。

创建

使用gorm.DB中的Create方法,GORM会根据传给Create()方法的模型,向数据表插入一行。

func (s *DB) Create(value interface{}) *DB //创建一行
func (s *DB) NewRecord(value interface{}) bool //根据自增ID判断主键是否还在

示例

func main{
    defer db.close()
    //具体的逻辑
    u := &User{Username: "user1", Password:"123456", Email:"123456789@outlook.com", Phone:"10123456789"}
    db.Create(u)
    if db.NewRecord(u){
        fmt.Println('写入失败')
    }
    else{
        fmt.Println('写入成功')
    }
}

查询

GROM框架在sql/database包的原生基础上封装了简便的方法,可以直接调用便将数据映射到对应的结构体模型中,用起来非常简单,如下面这几个方法:

//返回第一条 
func (s *DB) First(out interface{}, where ...interface{}) *DB 
//返回最后一条 
func (s *DB) Last(out interface{}, where ...interface{}) *DB 
//返回符合条件的内容 
func (s *DB) Find(out interface{}, where ...interface{}) *DB 
//返回Count(*)结果 
func (s *DB) Count(value interface{}) *DB

示例

//Find方法示例 
func find() { 
    var users = make([]*User, 0)
    db.Model(&User2{}).Find(&users)
    fmt.Println(users) 
} 
//First方法示例 
func first() { 
    var user1,user2 
    User db.First(&user1)
    fmt.Println(user1) 
    db.First(&user2,"id = ?",20) 
    fmt.Println(user2) 
} 
//Last方法示例 
func last() { 
    var user1,user2 
    User db.Last(&user1)
    fmt.Println(user1) 
    db.First(&user2,"id = ?",19) 
    fmt.Println(user2) 
} 
//Count方法示例 
func count() { 
    var count int 
    db.Model(&User{}).Count(&count)
    fmt.Println(count) 
}

更新

更新数据可以使用gorm.DBSave()Update(),UpdateColumn(),UpdateColumns(),Updates()等方法,后面这四个方法需要与Model()方法一起使用。

func (s *DB) Save(value interface{}) *DB

func (s *DB) Model(value interface{}) *DB 
//下面的方法需要与Model方法一起使用,通过Model方法指定更新数据的条件 
func (s *DB) Update(attrs ...interface{}) *DB 
func (s *DB) UpdateColumn(attrs ...interface{}) *DB 
func (s *DB) UpdateColumns(values interface{}) *DB 
func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB

示例

//Save()方法示例 
func save(){ 
    u := &User{} 
    db.First(u) 
    u.Email = "test@163.com" 
    db.Save(u) 
    fmt.Println(u) 
} 
//Update方法示例 
func update() { 
    u := &User{} 
    db.First(u) 
    db.Model(u).Update("username", "hello") 
} 
//Updates方法示例 
func updates() { 
    u := &User{} 
    db.First(u)
    db.Model(&u).Updates(map[string]interface{}{"username": "hello2"}) 
}

删除

使用gorm.DBDelete()方法可以很简单地删除满足条件的记录,下面是Delete()方法的定义:

//value如果有主键id,则包含在判断条件内,通过where可以指定其他条件 
func (s *DB) Delete(value interface{}, where ...interface{}) *DB

示例

func delete(){
    defer db.Close()
    u := &User{Id: 16}
    db.Delete(u)//根据ID
    db.Delete(&User{},"username = ?","user1")//根据额外条件删除
}

小结

本文对GORM框架进行了简单的介绍,以及框架的连接和简单操作数据库,GORM还有很多功能供我们开发更加流畅简洁。