-
builder模式
-
泛型约束
type Query struct {
SQL string
Args []any
}
type QueryBuilder interface {
Build() (*Query, error)
}
type Querier[T any] interface {
// Get 列、聚合函数、子查询
Get(ctx context.Context) (any, error)
GetMutli(ctx context.Context) ([]any, error)
}
var _ Querier[data.User] = &Selector[data.User]{}
type Executer interface {
Execute(ctx context.Context) *orm.QueryResult
}
var _ Executer = &Inserter[data.User]{}
type OnDuplicateKeyBuilder[T any] struct {
i *Inserter[T]
conflictColumns []predicate.Column
}
func (o *OnDuplicateKeyBuilder[T]) Update(assigns ...predicate.Assignable) *Inserter[T] {
o.i.OnDuplicateKey = &dialect.OnDuplicateKey{
Assigns: assigns,
ConflictColumns: o.conflictColumns,
}
return o.i
}
NewInserter[data.User](db).GetOnDuplicateKeyBuilder().Update(predicate.Assign("Email", "更新重复1357"))
// Expression 标记 表示 语句 或 语句的部分
type Expression interface {
expr()
}
var _ Expression = Column{}
var _ Expression = Aggregate{}
var _ Expression = RawExpr{}
var _ Expression = Predicate{}
var _ Expression = Valuer{}
selector中通过.Select(select selectable)使用
// Selectable 标记 canSelect 列、聚合函数、子查询、表达式
// Selectable 的部分都可以设置别名,即Aliasable
type Selectable interface {
Selectable()
}
var _ Selectable = Column{}
var _ Selectable = Aggregate{}
var _ Selectable = RawExpr{}
聚合函数,比如:AVG(columnName)
insertor中常在BuildOnduplicateKey时使用
// Assignable 标记接口
// 实现该接口意味着用于赋值语句
// 用于UPDATE、UPSERT 语句
type Assignable interface {
Assign()
}
predicate.C("Id").Lt(predicate.Valuer{Value: val})
selector中.where(predicates...predicate.Predicate)
type Predicate struct {
Left Expression
Op Op
Right Expression
}
允许用户自定义输入
type Dialect interface {
Quoter() string
BuildOnDuplicateKey(OnDuplicateKey *OnDuplicateKey) (*OnDuplicateKeyStatement, error)
}
var _ Dialect = &StandardSQL{}
var _ Dialect = &MysqlSQL{}
quoter -> 双引号
duplicateKey语句: on conflict columnName do update set col1=exclued.col1
quoter -> `
duplicateKey语句:on duplicate key update col1=values(col1)
type OnDuplicateKey struct {
Assigns []predicate.Assignable // 支持两种形式 col=values(col)、col=具体值
ConflictColumns []predicate.Column // 冲突列 standardSql语句构造使用
}
// Session 是 db、tx的顶层抽象
type Session interface {
GetCore() Core
ExecContext(ctx context.Context, query string, args ...any) *sql2.QueryResult
QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
}
var _ Session = &DB{}
var _ Session = &Tx{}
func NewSelector[T any](sess session.Session) *Selector[T] {
return &Selector[T]{
sess: sess,
SQLBuilder: sql2.SQLBuilder{Core: sess.GetCore()},
}
}
// 在selector中传入session(db | tx)在get、getMuti时调用相应的queryCtx方法执行语句拿到结果
s := selector.NewSelector[data.User](tx)
支持doTx(闭包事务)、beginTx
-
维护User和数据库中相应表、字段的关系
-
register(注册中心)
- 维护models,支持注册model、缓存model、get model
// Value 是对结构体实例的内部抽象
type Value interface {
SetColumns(rows *sql.Rows) error
Field(name string) (any, error)
}
type ValueCreator func(val any, model *register.Model) Value
SetColumns(): selector中将db返回结果通过row.Scan塞进&user{}中
Field(): insertor中遍历&user{Name: "zly", Birthdate: "1999-06-06"}获取每个字段及其值生成相应的sql语句
支持unsafe、reflect两种方式,unsafe性能更好,默认使用unsafe
做数据观测、统计时用
type Handler func(ctx context.Context, qc *orm.QueryContext) *orm.QueryResult
type Middleware func(next Handler) Handler
依靠ast生成常用模板语句
func UserIdLt(val int) predicate.Predicate {
return predicate.C("Id").Lt(predicate.Valuer{Value: val})
}
s := selector.NewSelector[data.User](tx).Where(data.UserIdLt(10))
