package db import ( "gorm.io/gorm" ) type Repository[T any] struct { db *gorm.DB pk string // 默认 id } func NewRepository[T any](db ...*gorm.DB) *Repository[T] { for _, d := range db { return NewRepositoryWith[T](d) } return NewRepositoryWith[T](DB()) } func NewRepositoryWith[T any](db *gorm.DB, pk ...string) *Repository[T] { r := &Repository[T]{db: db, pk: "id"} for _, s := range pk { if s != "" { r.pk = s return r } } return r } // Create 创建数据 func (r *Repository[T]) Create(entity *T) error { return r.db.Model(&entity).Create(&entity).Error } func (r *Repository[T]) Delete(expr *Expr) (int64, error) { var entity T res := r.db.Model(&entity).Scopes(expr.Scopes).Delete(&entity) return res.RowsAffected, res.Error } func (r *Repository[T]) DeleteByID(id any) error { var entity T return r.db.Delete(&entity, r.pk, id).Error } func (r *Repository[T]) Update(expr *Expr, values map[string]any) (int64, error) { res := r.db.Scopes(expr.Scopes).Updates(values) return res.RowsAffected, res.Error } func (r *Repository[T]) UpdateByID(id any, values map[string]any) error { var entity T return r.db.Model(&entity).Where(r.pk, id).Updates(values).Error } func (r *Repository[T]) GetByID(id any) (*T, error) { var entity T err := r.db.Model(&entity).Where(r.pk, id).First(&entity).Error if err != nil { return nil, err } return &entity, nil } func (r *Repository[T]) Find(expr ...*Expr) ([]*T, error) { var entity T var items []*T err := r.db.Model(&entity).Scopes(func(tx *gorm.DB) *gorm.DB { for _, e := range expr { tx = e.Scopes(tx) } return tx }).Find(&items).Error if err != nil { return nil, err } return items, nil } func (r *Repository[T]) Paginate(expr ...*Expr) (*Pager[T], error) { qb := NewQueryBuilder[T](r.db) for _, e := range expr { qb.Expr = *e } return qb.Paginate() } func (r *Repository[T]) NewDeleteBuilder() *DeleteBuilder[T] { return NewDeleteBuilder[T](r.db) } func (r *Repository[T]) NewUpdateBuilder() *UpdateBuilder[T] { return NewUpdateBuilder[T](r.db) } func (r *Repository[T]) NewQueryBuilder() *QueryBuilder[T] { return NewQueryBuilder[T](r.db) }