24-gin实现todolist

95 阅读3分钟

gin实现todolist

安装 .ini文件解析工具

这个是获取配置文件信息的

基本使用如下:

  • 根目录创建 conf/app.ini
app_name = jiangxiaobai gin
log_level = DEBUG

[mysql]
ip       = 127.0.0.1
port     = 3306
user     = root
password = 123456
database = todolist

[redis]
ip   = 127.0.0.1
port = 6379
  • 使用展示 main.go
package main

import (
	"fmt"
	"os"

	"github.com/gin-gonic/gin"
	"gopkg.in/ini.v1"
)

func main() {
	r := gin.Default()

	// gopkg.in/ini.v1 模块的演示
	config, err := ini.Load("./conf/api.ini")
	if err != nil {
		fmt.Println("Fail to read file:", err)
		os.Exit(1) //退出
	}

    // => 获取 .ini配置文件信息 
	// 获取app_name
	fmt.Println(config.Section("").Key("app_name").String())//jiangxiaobai gin
	// 获取 mysql下的password
	fmt.Println(config.Section("mysql").Key("password").String())//123456
    
    // .ini 文件写入数据
	config.Section("").Key("app_name").SetValue("smallmi gin") //修改
	config.Section("").Key("admin_path").SetValue("/admin")    //新增
	config.SaveTo("./conf/api.ini")                            //写入保存

	r.Run()
}

Gin 中使用 GORM 操作数据 mysql数据库

GORM简单介绍

  • GORM是Golang的一个orm框架。
    • orm 就是通过实例对象的语法,完成关系型数据库的操作的技术
    • 对象-关系映射(Object-Relational Mapping)的缩写
    • 使用 orm 框架可以让我们更方便的操作数据库
  • GORM 官方支持的数据库类型: MYSQL、PostgreSQL、SQlite、SQL Server
  • 官网:https://gorm.io/zh_CN/docs/index.html

安装 gorm

  • go get -u gorm.io/gorm
  • go get -u gorm.io/driver/mysql
    • /sqlite -> 指的是 SQlite
    • /mysql -> 这里我们用的

创建 db/mysql.go

package db

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

func Connect() *gorm.DB {
	// 读取 .ini里面的数据库配置todo
    user := config.Section("mysql").Key("user").String()
    password := config.Section("mysql").Key("password").String()
    port := config.Section("mysql").Key("port").String()
    ip := config.Section("mysql").Key("ip").String()
    database := config.Section("mysql").Key("database").String()
    
    dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)\/%v?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip,port, database)
	// dsn := "root:123456@tcp(127.0.0.1:3306)/" + dbName + "?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println(err)
		panic(err.Error())
	}

	return db
}

models 模型层

  • models/todolist
package models

import (
	"database/sql"
	"time"
)

type GormModule struct {
	Id        uint         `json:"id" gorm:"primarykey"`
	CreatedAt time.Time    `json:"created_at"`
	UpdatedAt time.Time    `json:"updated_at"`
	DeletedAt sql.NullTime `json:"deleted_at" gorm:"index"`
}

type TodoList struct {
	// gorm.Model 直接用是没法转小写的
	GormModule
	Content   string `json:"content"`
	Completed bool   `json:"completed"`
}

controllers 控制层

  • 创建 controller/todolist
package controller

import (
	"net/http"
	"smallmiproject/service"

	"github.com/gin-gonic/gin"
)

type PostBody struct {
	Id      uint   `json:"id"`
	Content string `json:"content"`
}

type TodoList struct {
	service.TodoList
}

// 跨域的中间件
func (list *TodoList) Cors(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")             //同意跨域的源
	c.Header("Access-Control-Allow-Headers", "Content-Type") //允许头部
	c.Header("Access-Control-Allow-Methods", "POST, GET")    //允许调用的方法

	if c.Request.Method == "OPTIONS" { // OPTIONS请求快速返回,不做处理
		c.JSON(http.StatusOK, "")
		c.Abort() //终止掉
		return
	}
	c.Next() // 继续处理请求
}
func (list *TodoList) List(c *gin.Context) {
	result := list.GetList()
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "ok",
		"data": result,
	})
}
func (list *TodoList) Add(c *gin.Context) {
	var body PostBody
	c.ShouldBindJSON(&body)

	result := list.AddTodo(body.Content)

	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "ok",
		"data": result,
	})
}
func (list *TodoList) Toggle(c *gin.Context) {
	var body PostBody
	c.ShouldBindJSON(&body)

	result := list.ToggleTodo(body.Id)

	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "ok",
		"data": result,
	})
}
func (list *TodoList) Delete(c *gin.Context) {
	var body PostBody
	c.ShouldBindJSON(&body)

	result := list.RemoveTodo(body.Id)

	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "ok",
		"data": result,
	})
}

service 层

  • 创建 service/todolist.go
package service

import (
	"smallmiproject/models"

	"gorm.io/gorm"
)

type TodoList struct {
	*gorm.DB
}

func (list *TodoList) GetList() []models.TodoList {
	var todos []models.TodoList
	//id 倒序
	list.Order("id desc").Find(&todos)

	return todos
}

func (list *TodoList) AddTodo(content string) uint {
	todo := models.TodoList{
		Content:   content,
		Completed: false,
	}

	// 添加到表中
	list.Create(&todo)

	return todo.Id
}

func (list *TodoList) ToggleTodo(id uint) uint {
	// 方式一
	var completed bool
	list.Model(&models.TodoList{}).Where("id = ?", id).Select("completed").Scan(&completed)
	list.Model(&models.TodoList{}).Where("id = ?").Update("completed", !completed)

	return id

	/*
		方式二
		var todo models.TodoList
		list.Where("id =?", id).First(&todo)

		if todo.Completed {
			todo.Completed = false
		} else {
			todo.Completed = true
		}
		list.Save(&todo)
		return id
	*/
}

func (list *TodoList) RemoveTodo(id uint) uint {
	list.Delete(&models.TodoList{}, id) //方式一
	// list.Where("id = ?", id).Delete(&models.TodoList{}) //方式二
	return id
}

main.go

package main

import (
	controller "smallmiproject/controllers"
	"smallmiproject/db"
	"smallmiproject/service"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	db := db.Connect()
	// 同步一张表进入数据库(自动迁移) 第一次执行后注释掉
	// db.AutoMigrate(&models.TodoList{})
	todoListService := service.TodoList{DB: db}
	todoListController := controller.TodoList{TodoList: todoListService}

	r.Use(todoListController.Cors) //跨域配置
	r.GET("/list", todoListController.List)
	r.POST("/add", todoListController.Add)
	r.POST("/toggle", todoListController.Toggle)
	r.POST("/delete", todoListController.Delete)

	r.Run(":8080")
}