zoukankan      html  css  js  c++  java
  • GORM入门指南

    gorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。

    gorm介绍

    Github GORM

    中文官方网站内含十分齐全的中文文档,有了它你甚至不需要再继续向下阅读本文。

    安装

    go get -u github.com/jinzhu/gorm
    

    连接数据库

    连接不同的数据库都需要导入对应数据的驱动程序,GORM已经贴心的为我们包装了一些驱动程序,只需要按如下方式导入需要的数据库驱动即可:

    import _ "github.com/jinzhu/gorm/dialects/mysql"
    // import _ "github.com/jinzhu/gorm/dialects/postgres"
    // import _ "github.com/jinzhu/gorm/dialects/sqlite"
    // import _ "github.com/jinzhu/gorm/dialects/mssql"
    

    连接MySQL

    import (
      "github.com/jinzhu/gorm"
      _ "github.com/jinzhu/gorm/dialects/mysql"
    )
    
    func main() {
      db, err := gorm.Open("mysql", "user:password@(localhost)/dbname?charset=utf8mb4&parseTime=True&loc=Local")
      defer db.Close()
    }
    

    连接PostgreSQL

    基本代码同上,注意引入对应postgres驱动并正确指定gorm.Open()参数。

    import (
      "github.com/jinzhu/gorm"
      _ "github.com/jinzhu/gorm/dialects/postgres"
    )
    
    func main() {
      db, err := gorm.Open("postgres", "host=myhost port=myport user=gorm dbname=gorm password=mypassword")
      defer db.Close()
    }
    

    连接Sqlite3

    基本代码同上,注意引入对应sqlite驱动并正确指定gorm.Open()参数。

    import (
      "github.com/jinzhu/gorm"
      _ "github.com/jinzhu/gorm/dialects/sqlite"
    )
    
    func main() {
      db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
      defer db.Close()
    }
    

    连接SQL Server

    基本代码同上,注意引入对应mssql驱动并正确指定gorm.Open()参数。

    import (
      "github.com/jinzhu/gorm"
      _ "github.com/jinzhu/gorm/dialects/mssql"
    )
    
    func main() {
      db, err := gorm.Open("mssql", "sqlserver://username:password@localhost:1433?database=dbname")
      defer db.Close()
    }
    

    GORM基本示例

    注意:

    1. 本文以MySQL数据库为例,讲解GORM各项功能的主要使用方法。
    2. 往下阅读本文前,你需要有一个能够成功连接上的MySQL数据库实例。

    Docker快速创建MySQL实例

    很多同学如果不会安装MySQL或者懒得安装MySQL,可以使用一下命令快速运行一个MySQL8.0.19实例,当然前提是你要有docker环境…

    在本地的13306端口运行一个名为mysql8019,root用户名密码为root1234的MySQL容器环境:

    docker run --name mysql8019 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -d mysql:8.0.19
    

    在另外启动一个MySQL Client连接上面的MySQL环境,密码为上一步指定的密码root1234:

    docker run -it --network host --rm mysql mysql -h127.0.0.1 -P13306 --default-character-set=utf8mb4 -uroot -p
    

    创建数据库

    在使用GORM前手动创建数据库db1

    CREATE DATABASE db1;

    GORM操作MySQL

    使用GORM连接上面的db1进行创建、查询、更新、删除操作。

    package main
    
    import (
    	"fmt"
    	"github.com/jinzhu/gorm"
    	_ "github.com/jinzhu/gorm/dialects/mysql"
    )
    
    // UserInfo 用户信息
    type UserInfo struct {
    	ID uint
    	Name string
    	Gender string
    	Hobby string
    }
    
    
    func main() {
    	db, err := gorm.Open("mysql", "root:root1234@(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
    	if err!= nil{
    		panic(err)
    	}
    	defer db.Close()
    
    	// 自动迁移
    	db.AutoMigrate(&UserInfo{})
    
    	u1 := UserInfo{1, "七米", "男", "篮球"}
    	u2 := UserInfo{2, "沙河娜扎", "女", "足球"}
    	// 创建记录
    	db.Create(&u1)
    	db.Create(&u2)
    	// 查询
    	var u = new(UserInfo)
    	db.First(u)
    	fmt.Printf("%#v
    ", u)
    
    	var uu UserInfo
    	db.Find(&uu, "hobby=?", "足球")
    	fmt.Printf("%#v
    ", uu)
    
    	// 更新
    	db.Model(&u).Update("hobby", "双色球")
    	// 删除
    	db.Delete(&u)
    }
    

    GORM Model定义

    在使用ORM工具时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针。 同时也支持sql.Scannerdriver.Valuer接口(interfaces)。

    gorm.Model

    为了方便模型定义,GORM内置了一个gorm.Model结构体。gorm.Model是一个包含了ID, CreatedAt, UpdatedAt, DeletedAt四个字段的Golang结构体。

    // gorm.Model 定义
    type Model struct {
      ID        uint `gorm:"primary_key"`
      CreatedAt time.Time
      UpdatedAt time.Time
      DeletedAt *time.Time
    }
    

    你可以将它嵌入到你自己的模型中:

    // 将 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`字段注入到`User`模型中
    type User struct {
      gorm.Model
      Name string
    }
    

    当然你也可以完全自己定义模型:

    // 不使用gorm.Model,自行定义模型
    type User struct {
      ID   int
      Name string
    }
    

    模型定义示例

    type User struct {
      gorm.Model
      Name         string
      Age          sql.NullInt64
      Birthday     *time.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:"-"` // 忽略本字段
    }
    

    结构体标记(tags)

    使用结构体声明模型时,标记(tags)是可选项。gorm支持以下标记:

    支持的结构体标记(Struct tags)

    结构体标记(Tag)描述
    Column 指定列名
    Type 指定列数据类型
    Size 指定列大小, 默认值255
    PRIMARY_KEY 将列指定为主键
    UNIQUE 将列指定为唯一
    DEFAULT 指定列默认值
    PRECISION 指定列精度
    NOT NULL 将列指定为非 NULL
    AUTO_INCREMENT 指定列是否为自增类型
    INDEX 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引
    UNIQUE_INDEX INDEX 类似,只不过创建的是唯一索引
    EMBEDDED 将结构设置为嵌入
    EMBEDDED_PREFIX 设置嵌入结构的前缀
    - 忽略此字段

    关联相关标记(tags)

    结构体标记(Tag)描述
    MANY2MANY 指定连接表
    FOREIGNKEY 设置外键
    ASSOCIATION_FOREIGNKEY 设置关联外键
    POLYMORPHIC 指定多态类型
    POLYMORPHIC_VALUE 指定多态值
    JOINTABLE_FOREIGNKEY 指定连接表的外键
    ASSOCIATION_JOINTABLE_FOREIGNKEY 指定连接表的关联外键
    SAVE_ASSOCIATIONS 是否自动完成 save 的相关操作
    ASSOCIATION_AUTOUPDATE 是否自动完成 update 的相关操作
    ASSOCIATION_AUTOCREATE 是否自动完成 create 的相关操作
    ASSOCIATION_SAVE_REFERENCE 是否自动完成引用的 save 的相关操作
    PRELOAD 是否自动完成预加载的相关操作

    主键、表名、列名的约定

    主键(Primary Key)

    GORM 默认会使用名为ID的字段作为表的主键。

    type User struct {
      ID   string // 名为`ID`的字段会默认作为表的主键
      Name string
    }
    
    // 使用`AnimalID`作为主键
    type Animal struct {
      AnimalID int64 `gorm:"primary_key"`
      Name     string
      Age      int64
    }
    

    表名(Table Name)

    表名默认就是结构体名称的复数,例如:

    type User struct {} // 默认表名是 `users`
    
    // 将 User 的表名设置为 `profiles`
    func (User) TableName() string {
      return "profiles"
    }
    
    func (u User) TableName() string {
      if u.Role == "admin" {
        return "admin_users"
      } else {
        return "users"
      }
    }
    
    // 禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user`
    db.SingularTable(true)
    

    也可以通过Table()指定表名:

    // 使用User结构体创建名为`deleted_users`的表
    db.Table("deleted_users").CreateTable(&User{})
    
    var deleted_users []User
    db.Table("deleted_users").Find(&deleted_users)
    //// SELECT * FROM deleted_users;
    
    db.Table("deleted_users").Where("name = ?", "jinzhu").Delete()
    //// DELETE FROM deleted_users WHERE name = 'jinzhu';
    

    GORM还支持更改默认表名称规则:

    gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string  {
      return "prefix_" + defaultTableName;
    }
    

    列名(Column Name)

    列名由字段名称进行下划线分割来生成

    type User struct {
      ID        uint      // column name is `id`
      Name      string    // column name is `name`
      Birthday  time.Time // column name is `birthday`
      CreatedAt time.Time // column name is `created_at`
    }
    

    可以使用结构体tag指定列名:

    type Animal struct {
      AnimalId    int64     `gorm:"column:beast_id"`         // set column name to `beast_id`
      Birthday    time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
      Age         int64     `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
    }
    

    时间戳跟踪

    CreatedAt

    如果模型有 CreatedAt字段,该字段的值将会是初次创建记录的时间。

    db.Create(&user) // `CreatedAt`将会是当前时间
    
    // 可以使用`Update`方法来改变`CreateAt`的值
    db.Model(&user).Update("CreatedAt", time.Now())
    

    UpdatedAt

    如果模型有UpdatedAt字段,该字段的值将会是每次更新记录的时间。

    db.Save(&user) // `UpdatedAt`将会是当前时间
    
    db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`将会是当前时间
    

    DeletedAt

    如果模型有DeletedAt字段,调用Delete删除该记录时,将会设置DeletedAt字段为当前时间,而不是直接将记录从数据库中删除。

  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/Golanguage/p/12285431.html
Copyright © 2011-2022 走看看