• Gin篇:gorm 使用


    连接数据库

    下面演示如果连接数据库,使用gorm.Open()方法可以初始化并返回一个gorm.DB结构体,这个结构体封装了GORM框架所有的数据库操作方法,下面是gorm.Open()方法的定义:

    func Open(dialect string, args ...interface{}) (db *DB, err error)

    示例代码:

    package main
    
    import "github.com/jinzhu/gorm"
    import _ "github.com/jinzhu/gorm/dialects/mysql"//导入连接MySQL数据库的驱动包
    
    //DSN
    const DSN = "root:123456@tcp(localhost:3306)/test?charset=utf8&parseTime=True&loc=Local"
    //指定驱动
    const DRIVER = "mysql"
    
    var db *gorm.DB
    
    func init() {
        var err error
        db,err = gorm.Open(DRIVER,DSN)
        if err != nil{
            panic(err)
        }
    }
    
    func main(){
        defer db.Close()//退出前执行关闭
        //调用db执行具体的逻辑
    }

    在上面的例子中,我们在init方法中初始化gorm.DB结构体,这样在下面的例子可以直接使用变量db直接进行数据库操作。

     

    基本操作

    使用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的结构体,GROM支持将结构体按规则映射为某个数据表的一行,结构体的每个字段表示数据表的列,结构体的字段首字母必须是大写的。

    创建

    使用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: "test_one", Password: "testOne123456", Email: "test_one@163.com", Phone: "13711112222"}
        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 = ? ","test_one")//根据额外条件删除
    }
    

      

    综合使用

    创建 main.go

     go get github.com/go-sql-driver/mysql 
     go get github.com/jinzhu/gorm

    代码

    package main
    
    import (
        _ "github.com/go-sql-driver/mysql"//加载mysql
        "github.com/jinzhu/gorm"//gorm 扩展包
        "fmt"
    )
    //注意如果 定义成小写username 引用时 无法调用
    type User struct {
        ID       int64  // 列名为 `id`
        Username string // 列名为 `username`
        Password string // 列名为 `password`
    }
    
    //设置表名
    func (User) TableName() string {
        return "users"
    }
    
    func main() {
        db, err := gorm.Open("mysql", "数据库用户名:数据库密码@tcp(ip地址:端口号)/数据库名?     charset=utf8&parseTime=True&loc=Local&timeout=10ms")
         defer db.Close()
        if err != nil {
            fmt.Printf("mysql connect error %v", err)
        }
    
        //执行迁移文件 生成数据表:如果数据库表已经存在,可以不做这一步
        db.CreateTable(&User{})
    
        //添加数据
        user := User{Username: "root", Password: "root"}
        result := db.Create(&user)
    
        if result.Error != nil {
            fmt.Printf("insert row err %v", result.Error)
            return
        }
    
        fmt.Println(user.ID) //返回id
    
        //查询单条数据
        getUser := User{}
    
        //SELECT id, first FROM users WHERE id = 1 LIMIT 1;
        db.Select([]string{"id", "username"}).First(&getUser, 1)
        fmt.Println(getUser) //打印查询数据
    
        //修改数据
        user.Username = "update username"
        user.Password = "update password"
        db.Save(&user)
    
        //查询列表数据
        users := []User{}
        db.Find(&users)
        fmt.Println(&users)//获取所有数据
    
      //删除数据
        db.Delete(&user)
    }
    

    执行

    go run main.go

     

    gin+gorm+router 快速搭建 crud restful API 接口

    ├──api
    │    ├── apis  
    │    │    └── user.go                   
    │    ├── database 
    │    │    └── mysql.go          
    │    ├── models 
    │    │    └── user.go       
    │    └── router 
    │         └──  router.go
    └──main.go
    

    apis/apis/user.go

    package apis
    
    import (
        "github.com/gin-gonic/gin"
        model "api/models"
        "net/http"
        "strconv"
    )
    
    //列表数据
    func Users(c *gin.Context) {
        var user model.User
        user.Username = c.Request.FormValue("username")
        user.Password = c.Request.FormValue("password")
        result, err := user.Users()
    
        if err != nil {
            c.JSON(http.StatusOK, gin.H{
                "code":    -1,
                "message": "抱歉未找到相关信息",
            })
            return
        }
    
        c.JSON(http.StatusOK, gin.H{
            "code": 1,
            "data":   result,
        })
    }
    
    //添加数据
    func Store(c *gin.Context) {
        var user model.User
        user.Username = c.Request.FormValue("username")
        user.Password = c.Request.FormValue("password")
        id, err := user.Insert()
    
        if err != nil {
            c.JSON(http.StatusOK, gin.H{
                "code":    -1,
                "message": "添加失败",
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "code":  1,
            "message": "添加成功",
            "data":    id,
        })
    }
    
    //修改数据
    func Update(c *gin.Context) {
        var user model.User
        id, err := strconv.ParseInt(c.Param("id"), 10, 64)
        user.Password = c.Request.FormValue("password")
        result, err := user.Update(id)
        if err != nil || result.ID == 0 {
            c.JSON(http.StatusOK, gin.H{
                "code":    -1,
                "message": "修改失败",
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "code":  1,
            "message": "修改成功",
        })
    }
    
    //删除数据
    func Destroy(c *gin.Context) {
        var user model.User
        id, err := strconv.ParseInt(c.Param("id"), 10, 64)
        result, err := user.Destroy(id)
        if err != nil || result.ID == 0 {
            c.JSON(http.StatusOK, gin.H{
                "code":    -1,
                "message": "删除失败",
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "code":  1,
            "message": "删除成功",
        })
    }

    database/mysql.go

    package database
    
    import (
        _ "github.com/go-sql-driver/mysql" //加载mysql
        "github.com/jinzhu/gorm"
        "fmt"
    )
    
    var Eloquent *gorm.DB
    
    func init() {
        var err error
        Eloquent, err = gorm.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local&timeout=10ms")
    
        if err != nil {
            fmt.Printf("mysql connect error %v", err)
        }
    
        if Eloquent.Error != nil {
            fmt.Printf("database error %v", Eloquent.Error)
        }
    }

    models/user.go

        package models
    
        import (
            orm "api/database"
        )
    
        type User struct {
            ID       int64  `json:"id"`       // 列名为 `id`
            Username string `json:"username"` // 列名为 `username`
            Password string `json:"password"` // 列名为 `password`
        }
    
        var Users []User
    
        //添加
        func (user User) Insert() (id int64, err error) {
    
            //添加数据
            result := orm.Eloquent.Create(&user)
            id =user.ID
            if result.Error != nil {
                err = result.Error
                return
            }
            return
        }
    
        //列表
        func (user *User) Users() (users []User, err error) {
            if err = orm.Eloquent.Find(&users).Error; err != nil {
                return
            }
            return
        }
    
        //修改
        func (user *User) Update(id int64) (updateUser User, err error) {
    
            if err = orm.Eloquent.Select([]string{"id", "username"}).First(&updateUser, id).Error; err != nil {
                return
            }
    
            //参数1:是要修改的数据
            //参数2:是修改的数据
            if err = orm.Eloquent.Model(&updateUser).Updates(&user).Error; err != nil {
                return
            }
            return
        }
    
        //删除数据
        func (user *User) Destroy(id int64) (Result User, err error) {
    
            if err = orm.Eloquent.Select([]string{"id"}).First(&user, id).Error; err != nil {
                return
            }
    
            if err = orm.Eloquent.Delete(&user).Error; err != nil {
                return
            }
            Result = *user
            return
        }
    

      

    router/router.go

    package router
    
    import (
        "github.com/gin-gonic/gin"
        . "api/apis"
    )
    
    func InitRouter() *gin.Engine {
        router := gin.Default()
    
        router.GET("/users", Users)
    
        router.POST("/user", Store)
    
        router.PUT("/user/:id", Update)
    
        router.DELETE("/user/:id", Destroy)
    
        return router
    }
    

      

    main.go

        package main
    
        import (
            _ "api/database"
            "api/router"
            orm "api/database"
        )
    
        func main() {
            defer orm.Eloquent.Close()
            router := router.InitRouter()
            router.Run(":8000")
        }
    

    执行 go run main.go

    访问地址

    POST localhost:8006/user 添加
    GET localhost:8006/users 列表
    DELETE localhost:8006/user/id 删除
    PUT localhost:8006/user/id 修改 

    原文作者:yourself
    转自链接:https://learnku.com/articles/23548/gingormrouter-quickly-build-crud-restful-api-interface
     

  • 相关阅读:
    易宝支付文档
    iOS 查看包架构信息
    kvc to nsdata
    设置windows status bar隐藏
    设计很大,PG VIA很多,怎么办?
    PrimePower
    Primetime里面的脚本小技巧
    PT里面如何使用AI实现功耗优化的成倍加速
    插不上PG VIA怎么办?
    如何控制各种filler的比例
  • 原文地址:https://www.cnblogs.com/-wenli/p/13748719.html
Copyright © 2020-2023  润新知