database

package module
v0.0.0-...-9ee81a8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2025 License: GPL-3.0 Imports: 28 Imported by: 0

README

使用指南

本库提供简洁的数据库操作接口,支持结构体与数据库表的映射、链式查询构建、零值过滤等功能。以下是快速入门指南。


前置条件

1. 模型注册

必须在使用前注册模型,以便 ORM 自动处理表结构映射:

import "github.com/skadiD/database"

// 定义模型结构体
type User struct {
    ID   int64  `orm:"id,pk,auto"`    // 使用 orm 标签指定列名 pk 主键 auto 自增
    Name string `db:"name"`
}

// 在 init 函数或包初始化阶段注册
func init() {
    // 注册模型:[类型参数] + 表名
    _ = database.RegisterModel[User]("users")
}

注意:

  • 必须为每个模型调用 RegisterModel
  • 表名需与数据库实际表名一致

快速开始

1. 初始化 ORM
import "github.com/skadiD/database"

func main() {
    // 创建模型实例
    user := User{Name: "Alice"}
    
    // 初始化 ORM 实例
    o := orm.Model[User](c).Load(&user)
}
2. 查询操作
// 查询所有字段
selector := o.Select()

// 自定义查询字段
selector := o.Select("id", "name")

// 添加条件
selector.Where(squirrel.Gt{"age": 18}).
    Where(squirrel.Like{"name": "%A%"})

// 排序和分页
selector.OrderBy("created_at DESC").
    Limit(10).
    Offset(0)

// 获取多条记录
results, err := selector.Get()

// 获取单条记录
user, err := selector.One()
3. 更新操作
// 自动过滤零值
updater := o.Update().
    Where(squirrel.Eq{"id": 123})

// 强制更新(包括零值)
affected, err := o.Save()

// 按需更新
affected, err := o.Update()
4. 插入操作
affected, err := o.Insert()
5. 删除操作
affected, err := o.Delete()

TODO

  • 支持事务
  • 支持多表查询
  • 支持代码生成

贡献与反馈

如有问题或建议,请提交 Issue 或 Pull Request。

Documentation

Index

Constants

View Source
const (
	MinPageElements = 10
)

Variables

View Source
var (
	StatementBuilder = psql
	DefaultHook      = func(b sq.SelectBuilder) sq.SelectBuilder {
		return b
	}
)
View Source
var CustomFieldTypes = map[string]map[string]string{}

Functions

func Delete

func Delete[T any](hook func(sq.DeleteBuilder) sq.DeleteBuilder) bool

Delete 为某表删除记录 返回是否成功

文档地址 https://github.com/Masterminds/squirrel

func Get

func Get[T any](db pgxscan.Querier, sb sq.SelectBuilder) (*T, error)

func GetAll

func GetAll[T any](table string, page, size uint64, hook func(sq.SelectBuilder) sq.SelectBuilder) ([]T, int)

GetAll 获取某表全部数据 通过 hook 钩子函数进行拓展

文档地址 https://github.com/Masterminds/squirrel

func GetAllByFields

func GetAllByFields[T any](table string, fields []string, sort []string, page, size uint64, hook func(sq.SelectBuilder) sq.SelectBuilder) ([]T, int)

func GetAllByFieldsCte

func GetAllByFieldsCte[T any](

	db pgxscan.Querier,

	fromTable,

	idField string,

	sort []string,

	page,

	size uint64,

	buildPreselect func(selectIdFrom sq.SelectBuilder) sq.SelectBuilder,

	buildPrimary func(selectPrimaryFrom sq.SelectBuilder) sq.SelectBuilder,
) ([]T, int, bool)

GetAllByFieldsCte 使用CTE实现将三个查询合并到同一语句来执行需要对主表JOIN和LIMIT的分页查询, 同时返回主表查询结果和主记录总数(用于分页)。 注意:当主表需要在JOIN的同时通过COUNT(*)来计算主记录的行数或LIMIT来限制主记录的行数(比如分页), 请使用此方法避免COUNT(*)结果偏大(主记录因为JOIN重复),或者JOIN得到的从表记录返回不完整(被LIMIT截断)。

-- 第一个CTE 预选全部ID(GROUP BY用于在预选条件中存在JOIN的情况下去重):

WITH __cte_all_ids AS (SELECT <id> FROM <主表> <预选条件>... GROUP BY <id> <ORDER>...),

-- 第二个CTE 计算总ID数:

__cte_count AS (SELECT COUNT(*) as pagination_total FROM cte_all_ids)

-- 实际查询: SELECT <主表字段>..., __cte_count.pagination_total FROM <主表> JOIN (SELECT <id> FROM __cte_all_ids <LIMIT> <OFFSET>) as __cts_ids ON __cte_ids.<id> = <主表>.<id> CROSS JOIN __cte_count

func GetCount

func GetCount(table string, hook func(sq.SelectBuilder) sq.SelectBuilder) int

GetCount 获取某表数据条数

文档地址 https://github.com/Masterminds/squirrel

func GetFixedPanicTrace

func GetFixedPanicTrace(kb int, hidePath bool) (string, int)

GetFixedPanicTrace 按照易读取的方式返回panic的堆栈信息和goroutine数量

func GetFormatTrace

func GetFormatTrace(r interface{}, kb int, hidePath bool, hideGor bool) string

GetFormatTrace 对panic堆栈信息进行格式化返回可进行Log的panic信息,r为recovery()返回的信息,kb为获取的堆栈信息的长度,hidePath为 是否隐藏路径信息,hideGor为是否隐藏goroutine信息

func GetOne

func GetOne[T any](tableName string, cols []string, hook func(sq.SelectBuilder) sq.SelectBuilder) (T, bool)

GetOne 获取某表一条数据 通过 hook 钩子函数进行拓展

使用本机 RowToStructByName,不支持联立 select * row2struct

文档地址 https://github.com/Masterminds/squirrel

func GetOne2

func GetOne2[T any](tableName string, cols []string, hook func(sq.SelectBuilder) sq.SelectBuilder) (T, bool)

GetOne2 获取某表一条数据 通过 hook 钩子函数进行拓展

使用 pgx.RowToStructByName,支持联立 select * row2struct

文档地址 https://github.com/Masterminds/squirrel

func GetOneFromStructNameTable

func GetOneFromStructNameTable[T any](cols []string, hook func(sq.SelectBuilder) sq.SelectBuilder) (T, bool)

GetOneFromStructNameTable 获取某表一条数据 通过 hook 钩子函数进行拓展

文档地址 https://github.com/Masterminds/squirrel

func GetPanicTrace

func GetPanicTrace(kb int) (stackStr string, gorouteLen int)

GetPanicTrace 获取最大长度为kb的panic堆栈信息,解析为string并搜索堆栈内goroutine数量

func GetRawPanicTrace

func GetRawPanicTrace(kb int) (stack []byte, length int)

GetRawPanicTrace 返回指定KB长度的panic堆栈信息和堆栈信息长度

func Insert

func Insert[T any](hook func(sq.InsertBuilder) sq.InsertBuilder) (T, bool)

Insert 为某表添加记录 返回是否成功

文档地址 https://github.com/Masterminds/squirrel

func IsZeroValue

func IsZeroValue(value any) bool

func RegisterModel

func RegisterModel[T any](tableName string) error

RegisterModel 注册表模型

Warning: 线程不安全

func RowToStructByName

func RowToStructByName[T any](row pgx.CollectableRow) (T, error)

func Select

func Select[T any](db pgxscan.Querier, sb sq.SelectBuilder) ([]T, error)

func ToCte

func ToCte[T sq.Sqlizer](alias string, expr T) T

func Update

func Update[T any](hook func(sq.UpdateBuilder) sq.UpdateBuilder) (T, bool)

Update 为某表更新记录 返回是否成功

文档地址 https://github.com/Masterminds/squirrel

func UpdateTx

func UpdateTx[T any](tx pgx.Tx, hook func(sq.UpdateBuilder) sq.UpdateBuilder) bool

UpdateTx 为某表更新记录 返回是否成功

文档地址 https://github.com/Masterminds/squirrel

func WithCte

func WithCte[T sq.Sqlizer](first Cte[T], rest ...Cte[T]) T

Types

type Client

type Client struct {
	Client *pgxpool.Pool
	// contains filtered or unexported fields
}

func NewClient

func NewClient(connString string) *Client

NewClient 初始化数据库

func (*Client) Delete

func (c *Client) Delete(sb squirrel.DeleteBuilder) (int64, error)

Delete 删除数据

func (*Client) Get

func (c *Client) Get(sb squirrel.SelectBuilder, result any) error

Get 查询单条

func (*Client) Insert

func (c *Client) Insert(sb squirrel.InsertBuilder) (int64, error)

Insert 插入数据

func (*Client) Select

func (c *Client) Select(sb squirrel.SelectBuilder, result any) error

Select 查询多条

func (*Client) ToStruct

func (c *Client) ToStruct()

func (*Client) Types

func (c *Client) Types(types []*pgtype.Type) *Client

Types 注册自定义类型

func (*Client) Update

func (c *Client) Update(sb squirrel.UpdateBuilder) (int64, error)

Update 修改数据

type Cte

type Cte[T sq.Sqlizer] struct {
	Alias string
	Expr  T
}

func NewCte

func NewCte[T sq.Sqlizer](alias string, expr T) Cte[T]

type FieldSchema

type FieldSchema struct {
	GoName     string       // Go字段名
	ColumnName string       // 数据库列名
	Offset     uintptr      // 字段偏移量
	GoType     reflect.Type // Go类型
	PrimaryKey bool         // 是否主键
	AutoIncr   bool         // 是否自增
}

FieldSchema 字段元数据

type TableSchema

type TableSchema struct {
	GoType        reflect.Type
	TableName     string
	Fields        []*FieldSchema
	PrimaryKey    *FieldSchema
	ColumnToField map[string]*FieldSchema
}

TableSchema 表元数据

func GetSchema

func GetSchema(model any) *TableSchema

GetSchema 获取表元数据

Directories

Path Synopsis
scan

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL