» Go:使用Gin构建REST API » 2. 开发 » 2.6 数据库:MySQL

数据库:MySQL

SQLite 只是为了效果演示。如果你需要一个生产环境可用的数据库,可尝试 MySQLmongoDB

切换到 MySQL

  1. 在你的机器上安装 MySQL 并启动。

注意:在实际生产项目中,记得给表中字段创建所需的索引。

  1. 添加 gorm 的 mysql 依赖:
go get -u gorm.io/driver/mysql
  1. 更新代码。

添加 infrastructure/database/mysql.go

/*
Package database 处理所有数据库持久化实现。
*/
package database

import (
	"context"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"

	"literank.com/rest-books/domain/model"
)

type MySQLPersistence struct {
	db *gorm.DB
}

func NewMySQLPersistence(dsn string) (*MySQLPersistence, error) {
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		return nil, err
	}
	// Auto Migrate the data structs
	db.AutoMigrate(&model.Book{})

	return &MySQLPersistence{db}, nil
}

func (s *MySQLPersistence) CreateBook(ctx context.Context, b *model.Book) (uint, error) {
	if err := s.db.WithContext(ctx).Create(b).Error; err != nil {
		return 0, err
	}
	return b.ID, nil
}

func (s *MySQLPersistence) UpdateBook(ctx context.Context, id uint, b *model.Book) error {
	var book model.Book
	if err := s.db.WithContext(ctx).First(&book, id).Error; err != nil {
		return err
	}
	return s.db.WithContext(ctx).Model(book).Updates(b).Error
}

func (s *MySQLPersistence) DeleteBook(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Delete(&model.Book{}, id).Error
}

func (s *MySQLPersistence) GetBook(ctx context.Context, id uint) (*model.Book, error) {
	var book model.Book
	if err := s.db.WithContext(ctx).First(&book, id).Error; err != nil {
		return nil, err
	}
	return &book, nil
}

func (s *MySQLPersistence) GetBooks(ctx context.Context) ([]*model.Book, error) {
	books := make([]*model.Book, 0)
	if err := s.db.WithContext(ctx).Find(&books).Error; err != nil {
		return nil, err
	}
	return books, nil
}

注意与之前的关键区别,在 gorm.Open(mysql.Open(dsn), &gorm.Config{}) 处使用 mysql.Open(dsn) 而不是 sqlite.Open(fileName)

DSN 表示数据源名称(Data Source Name)。它是用于向应用程序提供数据实例连接信息的字符串。

DBConfig 结构体添加 DSN 配置项,在 infrastructure/config/config.go 中:

 type DBConfig struct {
        FileName string `json:"file_name" yaml:"file_name"`
+       DSN      string `json:"dsn" yaml:"dsn"`
 } 

更新 WireHelper 以切换依赖,在 application/wire_helper.go 中:

@@ -8,11 +8,11 @@ import (
 
 // WireHelper is the helper for dependency injection
 type WireHelper struct {
-       persistence *database.SQLitePersistence
+       persistence *database.MySQLPersistence
 }
 
 func NewWireHelper(c *config.Config) (*WireHelper, error) {
-       db, err := database.NewSQLitePersistence(c.DB.FileName)
+       db, err := database.NewMySQLPersistence(c.DB.DSN)
        if err != nil {
                return nil, err
        }

main.go 中放入 DSN 值:

@@ -15,6 +15,7 @@ func main() {
                },
                DB: config.DBConfig{
                        FileName: "test.db",
+                       DSN:      "test_user:test_pass@tcp(127.0.0.1:3306)/lr_book?charset=utf8mb4&parseTime=True&loc=Local",
                },
        }
        // Prepare dependencies

瞧!你的 API 服务器现在由 MySQL 驱动啦!