Skip to content

Spend less time managing your data and more time making decisions with goal-web/database.

License

Notifications You must be signed in to change notification settings

goal-web/database

Repository files navigation

Goal-web/database

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) any {
		return database.Config{
			Default: env.StringOptional("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.StringOptional("db.charset", "utf8mb4"),
					"collation":       env.StringOptional("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.StringOptional("db.pgsql.charset", "utf8mb4"),
					"prefix":          env.GetString("db.pgsql.prefix"),
					"schema":          env.StringOptional("db.pgsql.schema", "public"),
					"sslmode":         env.StringOptional("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.Query[T] {
	// 测试用例环境下的简易 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

// TestMysqlDatabaseWithoutApplication 只需要给给 table 包设置一个可用的 contracts.DBFactory 即可正常使用 table 下面的数据库操作方法
func TestMysqlDatabaseWithoutApplication(t *testing.T) {
	table.SetFactory(database.NewFactory(database.Config{
		Default: "mysql",
		Connections: map[string]contracts.Fields{
			"mysql": {
				"driver":    "mysql",
				"host":      "localhost",
				"port":      "3306",
				"database":  "goal",
				"username":  "root",
				"password":  "123456",
				"charset":   "utf8mb4",
				"collation": "utf8mb4_unicode_ci",
			},
		},
	}, nil))

	assert.True(t, table.Query("users").Count() == 0)

	user := table.Query("users").Create(contracts.Fields{
		"name": "testing",
	})
	assert.NotNil(t, user)
	assert.True(t, user.(contracts.Fields)["name"] == "testing")
	assert.True(t, table.Query("users").Count() == 1)
	table.Query("users").Where("name", "testing").Delete()
	assert.True(t, table.Query("users").Count() == 0)
}

goal-web
goal-web/database
[email protected]

About

Spend less time managing your data and more time making decisions with goal-web/database.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages