千呼萬喚使出來,goal 資料庫元件終於出爐啦

qbhy發表於2022-01-26

goal-web/database
goal 框架的資料庫元件,當然你也可以在 goal 之外的框架使用他。

目前資料庫元件暫時不能使用關聯關係,你可以用 WhereExists 來代替

安裝 - install

go get github.com/goal-web/database

使用 - usage

goal 的腳手架自帶了絕大多數開發一個 web 應用的所需要的功能和元件,當然包括了資料庫元件。一般情況下,我們只需要在 .env 修改自己的資料庫配置即可,新增資料庫連線可以 config/database.go 修改 Connections 屬性。

配置 - config

預設情況下,config/database.go 配置檔案像下面那樣,預設新增了 sqlite、MySQL、postgresSql 三個資料庫連線的配置

Laravel 不同的是,goal 把 redis 配置獨立出去了,因為 redis 也是一個獨立的模組,不想讓 redis 依賴 database

package config
import (
    "github.com/goal-web/contracts"
    "github.com/goal-web/database"
)
func init() {
    configs["database"] = func(env contracts.Env) interface{} {
        return database.Config{
            Default: env.StringOption("db.connection", "mysql"),
            Connections: map[string]contracts.Fields{
                "sqlite": {
                    "driver":   "sqlite",
                    "database": env.GetString("sqlite.database"),
                },
                "mysql": {
                    "driver":          "mysql",
                    "host":            env.GetString("db.host"),
                    "port":            env.GetString("db.port"),
                    "database":        env.GetString("db.database"),
                    "username":        env.GetString("db.username"),
                    "password":        env.GetString("db.password"),
                    "unix_socket":     env.GetString("db.unix_socket"),
                    "charset":         env.StringOption("db.charset", "utf8mb4"),
                    "collation":       env.StringOption("db.collation", "utf8mb4_unicode_ci"),
                    "prefix":          env.GetString("db.prefix"),
                    "strict":          env.GetBool("db.struct"),
                    "max_connections": env.GetInt("db.max_connections"),
                    "max_idles":       env.GetInt("db.max_idles"),
                },
                "pgsql": {
                    "driver":          "postgres",
                    "host":            env.GetString("db.pgsql.host"),
                    "port":            env.GetString("db.pgsql.port"),
                    "database":        env.GetString("db.pgsql.database"),
                    "username":        env.GetString("db.pgsql.username"),
                    "password":        env.GetString("db.pgsql.password"),
                    "charset":         env.StringOption("db.pgsql.charset", "utf8mb4"),
                    "prefix":          env.GetString("db.pgsql.prefix"),
                    "schema":          env.StringOption("db.pgsql.schema", "public"),
                    "sslmode":         env.StringOption("db.pgsql.sslmode", "disable"),
                    "max_connections": env.GetInt("db.pgsql.max_connections"),
                    "max_idles":       env.GetInt("db.pgsql.max_idles"),
                },
            },
        }
    }
}

.env 的資料庫相關配置

# 預設連線
db.connection=sqlite

sqlite.database=/Users/qbhy/project/go/goal-web/goal/example/database/db.sqlite

db.host=localhost
db.port=3306
db.database=goal
db.username=root
db.password=password

db.pgsql.host=localhost
db.pgsql.port=55433
db.pgsql.database=postgres
db.pgsql.username=postgres
db.pgsql.password=123456

定義模型 - define a model

app/models/user.go 檔案

package models

import (
    "github.com/goal-web/database/table"
    "github.com/goal-web/supports/class"
)

// UserClass 這個類變數,以後大有用處
var UserClass = class.Make(new(User))

// UserModel 返回 table 例項,繼承自查詢構造器並且實現了所有 future
func UserModel() *table.Table {
    return table.Model(UserClass, "users")
}

// User 模型結構體
type User struct {
    Id       int64  `json:"id"`
    NickName string `json:"name"`
}

用法 - method of use

package tests

import (
    "fmt"
    "github.com/goal-web/contracts"
    "github.com/goal-web/database/table"
    "github.com/goal-web/example/models"
    "github.com/stretchr/testify/assert"
    "testing"
)

func getQuery(name string) contracts.QueryBuilder {
    // 測試用例環境下的簡易 goal 應用啟動
    app := initApp("/Users/qbhy/project/go/goal-web/goal/tests")

    //return  table.Query("users") 返回 table 例項,使用預設連線
    //tx, _ := app.Get("db").(contracts.DBConnection).Begin()
    //return table.WithTX("users", tx) // 事物環境下執行

    //return table.WithConnection(name, "sqlite") // 返回指定連線的 table 例項,使用連線名
    return table.WithConnection(name, app.Get("db").(contracts.DBConnection)) // 也可以指定連線例項
}

// TestTableQuery 測試不帶模型的 table 查詢,類似 laravel 的 DB::table()
func TestTableQuery(t *testing.T) {

    getQuery("users").Delete()

    // 不設定模型的情況下,返回 contracts.Fields
    user := getQuery("users").Create(contracts.Fields{
        "name": "qbhy",
    }).(contracts.Fields)

    fmt.Println(user)
    userId := user["id"].(int64)
    // 判斷插入是否成功
    assert.True(t, userId > 0)

    // 獲取資料總量
    assert.True(t, getQuery("users").Count() == 1)

    // 修改資料
    num := getQuery("users").Where("name", "qbhy").Update(contracts.Fields{
        "name": "goal",
    })
    assert.True(t, num == 1)
    // 判斷修改後的資料
    user = getQuery("users").Where("name", "goal").First().(contracts.Fields)

    err := getQuery("users").Chunk(10, func(collection contracts.Collection, page int) error {
        assert.True(t, collection.Len() == 1)
        fmt.Println(collection.ToJson())
        return nil
    })

    assert.Nil(t, err)

    assert.True(t, user["id"] == userId)
    assert.True(t, user["name"] == "goal")
    assert.True(t, getQuery("users").Find(userId).(contracts.Fields)["id"] == userId)
    assert.True(t, getQuery("users").Where("id", userId).Delete() == 1)
    assert.Nil(t, getQuery("users").Find(userId))
}

func TestModel(t *testing.T) {
    initApp("/Users/qbhy/project/go/goal-web/goal/tests")

    fmt.Println("用table查詢:",
        getQuery("users").Get().Map(func(user contracts.Fields) {
            fmt.Println("用table查詢", user)
        }).ToJson()) // query 返回 Collection<contracts.Fields>

    user := models.UserModel().Create(contracts.Fields{
        "name": "qbhy",
    }).(models.User)

    fmt.Println("建立後返回模型", user)

    fmt.Println("用table查詢:",
        getQuery("users").Get().Map(func(user contracts.Fields) {
            fmt.Println("用table查詢", user)
        }).ToJson()) // query 返回 Collection<contracts.Fields>

        // 用模型查詢
    fmt.Println(models.UserModel(). // model 返回 Collection<models.User>
                    Get().
                    Map(func(user models.User) {
            fmt.Println("id:", user.Id)
        }).ToJson())

    fmt.Println(models.UserModel().Where("id", ">", 0).Delete())
}

更多查詢構造器用法請移步 goal-web/querybuilder

在 goal 之外的框架使用 - use in frameworks other than goal

這部分內容比較多,這裡暫時不展開講,後面會專門錄影片介紹,歡迎大家點贊訂閱

goal-web
goal-web/database
qbhy0715@qq.com

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章