青训营 使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作,把实现过程整理成文章| 豆包MarsCode AI刷题

90 阅读4分钟

青训营 使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作,把实现过程整理成文章| 豆包MarsCode AI刷题

背景概要

在先前学习HTTP协议的时候,使用gin框架实现了一个bubble任务清单的小程序。其中数据通过json键值对传输到本地后,在本地程序中通过GORM连接至数据库,并实现相关增删改查操作。

image.png

功能实现需求

  • 查看所有待办事项:当打开网站发出get方法请求时,查询数据库中todo表中所有数据并返回。
  • 增加待办事项:当在网站上输入待办事项并点击加号时,通过post方法将输入json键值对传输到后端,并在数据库中添加待办事项。
  • 修改待办事项状态:当点击待办事项的勾号时,修改待办事项状态为完成,并在数据库中修改status为1。
  • 删除待办事项:点击待办事项的×号时,将待办事务删除,并删除数据库中相关数据。
  • 其中增加事务会自动通过主键id标识事务,而修改与删除需要根据id进行删除。

GORM的连接及CRUD相关操作

连接数据库

为了方便模块化结构,创建InitMySQL函数来进行连接数据库,其中在连接之后将数据库表与相关结构体进行绑定。在进行连接之前,先用sql语句在数据库中创建相关库。

  • 创建库名为bubble的数据库:

    CREATE DATABASE bubble CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    

    此时库已经建好可以进行连接操作。

  • 创造全局变量DB,相关结构体Todo以及连接参数dsn,并在连接之后处理错误并返回ping值:

    var Db *gorm.DB
    
    type Todo struct {
    	ID     int    `json:"id"`
    	Title  string `json:"title"`
    	Status bool   `json:"status" gorm:"default:false"`
    }
    
    func InitMySQL() (err error) {
    	dsn := "root:password@tcp(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
    	Db, err = gorm.Open("mysql", dsn)
    	if err != nil {
    		return
    	}
    	Db.AutoMigrate(Todo{})
    	return Db.DB().Ping()
    }
    
  • 同时为了防止忘记关闭数据库连接,创建CloseMySQL函数进行defer延迟关闭:

    func CloseMySQL() {
    	defer func(Db *gorm.DB) {
    		err := Db.Close()
    		if err != nil {
    			panic(err)
    		}
    	}(Db)
    }
    

增加Todo实例并在数据库中创建相应数据

  • 先在逻辑实现层创建todo结构体并接收POST方法传输的数据,在处理错误之后将指针传递给dao层:

    	var todo dao.Todo
    	err := c.BindJSON(&todo)
    	if err != nil {
    		return
    	}
    	err = dao.AddTodo(&todo)
    
  • 再在dao层由GORM在bubble库中创建相关数据 并处理错误,其中调用连接数据库的全局变量Db中的create方法来在数据库中创建实例:

    func AddTodo(todo *Todo) (err error) {
    	err = Db.Create(&todo).Error
    	return
    }
    
    

查询数据库中所有todo实例以及根据id查询某一特定实例:

  • 查询所有对象,通过Db中的Find方法即可以检索所有对象:

    func SearchTodo() (todolist []*Todo, err error) {
    	if err := Db.Find(&todolist).Error; err != nil {
    		return nil, err
    	}
    	return
    }
    
  • 根据传输参数id来查询到id所对应的todo实例。可以通过Db中的where方法来检索特定对象,再通过Find或者First方法来在数据库中检索对象并返回到todo结构体中:

    // FindTodo 找到id所对应todo实例
    func FindTodo(id string) (todo *Todo, err error) {
    	if err = Db.Where("id = ?", id).Find(&todo).Error; err != nil {
    		return nil, err
    	}
    	return
    }
    
    

根据id修改特定todo实例状态

  • 根据传输数据中的参数id来获取所要修改todo实例的id,再调用通过id查询具体实例的函数FindTodo:

    	id, _ := c.Params.Get("id")
    
    	todo, err := dao.FindTodo(id)
    
  • 再将todo中的status改为相反状态,并通过dao层的UpdateTodo函数来对修改后的todo进行更新。在该函数中通过Db的Save方法进行更新。Save是一个组合函数。如果保存值中不包含主键,它将执行 Create,否则它将执行 Update (包含所有字段):

    // UpdateTodo 更新相关todo实例
    func UpdateTodo(todo *Todo) (err error) {
    	err = Db.Save(&todo).Error
    	return
    }
    

根据id删除特定todo实例

  • 该功能实现思路与更新类似,通过传输数据中的id字段来找到todo实例,再进行删除操作。可以通过Db的where方法来检索id到特定实例,再调用Delete方法进行删除:

    //DeleteTodo 删除指定todo实例
    
    func DeleteTodo(id string) (err error) {
    	err = Db.Where("id=?", id).Delete(&Todo{}).Error
    	return
    }
    
    

总结与思考

在该bubble清单的小项目中,使用GORM来进行数据库相关增删改查功能。具体思路实现为先通过Db全局变量进行数据库连接并将todo实例与数据库中todo表进行绑定;通过create方法进行创建对象;通过where方法来检索对象;通过Find或者First方法进行查询;通过Save方法进行更新;通过Delete方法进行删除等。