V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  morebuff  ›  全部回复第 1 页 / 共 3 页
回复总数  47
1  2  3  
@cooooing 我自己项目中用的,模仿 mybatis-plus 封装了一点,平时用着方便
package db

import (
"context"

"gorm.io/gorm"
)

type Wrapper struct {
db *gorm.DB
}

func BuildWrapper() *Wrapper {
return &Wrapper{db: DB()}
}

// DB 获取原始 DB 和错误的方法
func (w *Wrapper) DB() *gorm.DB {
return w.db
}

func (w *Wrapper) GetError() error {
return w.db.Error
}

// EQ 等于
func (w *Wrapper) EQ(column string, value any) *Wrapper {
w.db = w.db.Where(column+" = ?", value)
return w
}

// NE 不等于
func (w *Wrapper) NE(column string, value any) *Wrapper {
w.db = w.db.Where(column+" <> ?", value)
return w
}

// GT 大于
func (w *Wrapper) GT(column string, value any) *Wrapper {
w.db = w.db.Where(column+" > ?", value)
return w
}

// GE 大于等于
func (w *Wrapper) GE(column string, value any) *Wrapper {
w.db = w.db.Where(column+" >= ?", value)
return w
}

// LT 小于
func (w *Wrapper) LT(column string, value any) *Wrapper {
w.db = w.db.Where(column+" < ?", value)
return w
}

// LE 小于等于
func (w *Wrapper) LE(column string, value any) *Wrapper {
w.db = w.db.Where(column+" <= ?", value)
return w
}

// Like 模糊查询
func (w *Wrapper) Like(column string, value any) *Wrapper {
w.db = w.db.Where(column+" LIKE ?", value)
return w
}

// NotLike 模糊查询
func (w *Wrapper) NotLike(column string, value any) *Wrapper {
w.db = w.db.Where(column+" NOT LIKE ?", value)
return w
}

// LikeLeft 模糊查询
func (w *Wrapper) LikeLeft(column string, value string) *Wrapper {
w.db = w.db.Where(column+" LIKE ?", "%"+value)
return w
}

// LikeRight 模糊查询
func (w *Wrapper) LikeRight(column string, value string) *Wrapper {
w.db = w.db.Where(column+" LIKE ?", value+"%")
return w
}

// NotLikeLeft 模糊查询
func (w *Wrapper) NotLikeLeft(column string, value string) *Wrapper {
w.db = w.db.Where(column+" NOT LIKE ?", "%"+value)
return w
}

// NotLikeRight 模糊查询
func (w *Wrapper) NotLikeRight(column string, value string) *Wrapper {
w.db = w.db.Where(column+" NOT LIKE ?", value+"%")
return w
}

// IN 批量查询
func (w *Wrapper) IN(column string, values any) *Wrapper {
w.db = w.db.Where(column+" IN ?", values)
return w
}

// NotIN 批量查询
func (w *Wrapper) NotIN(column string, values any) *Wrapper {
w.db = w.db.Not(column+" IN ?", values)
return w
}

// Between 区间查询
func (w *Wrapper) Between(column string, before, after any) *Wrapper {
w.db = w.db.Where(column+" BETWEEN ? AND ?", before, after)
return w
}

// NotBetween 区间查询
func (w *Wrapper) NotBetween(column string, before, after any) *Wrapper {
w.db = w.db.Where(column+" NOT BETWEEN ? AND ?", before, after)
return w
}

// Or 或者
func (w *Wrapper) Or(condition, value any) *Wrapper {
w.db = w.db.Or(condition, value)
return w
}

// OrderBy 排序 desc 是否倒序
func (w *Wrapper) OrderBy(column string, desc bool) *Wrapper {
if desc {
w.db = w.db.Order(column + " DESC")
} else {
w.db = w.db.Order(column + " ASC")
}
return w
}

// OrderByAsc 排序
func (w *Wrapper) OrderByAsc(column string) *Wrapper {
w.db = w.db.Order(column + " ASC")
return w
}

// OrderByDesc 排序 desc 是否倒序
func (w *Wrapper) OrderByDesc(column string) *Wrapper {
w.db = w.db.Order(column + " DESC")
return w
}

// GroupBy 分组
func (w *Wrapper) GroupBy(column string) *Wrapper {
w.db = w.db.Group(column)
return w
}

// Limit 限制条数
func (w *Wrapper) Limit(limit int) *Wrapper {
w.db = w.db.Limit(limit)
return w
}

// Offset 偏移量
func (w *Wrapper) Offset(offset int) *Wrapper {
w.db = w.db.Offset(offset)
return w
}

// Columns 指定字段
func (w *Wrapper) Columns(columns ...string) *Wrapper {
w.db = w.db.Select(columns)
return w
}

// Page 分页
func (w *Wrapper) Page(page, size int) *Wrapper {
w.db = w.db.Scopes(Page(page, size))
return w
}

// Scopes 使用构造器
func (w *Wrapper) Scopes(fn func(db *gorm.DB) *gorm.DB) *Wrapper {
w.db = w.db.Scopes(fn)
return w
}

// IsNull 判断字段为 NULL
func (w *Wrapper) IsNull(column string) *Wrapper {
w.db = w.db.Where(column + " IS NULL")
return w
}

// IsNotNull 判断字段不为 NULL
func (w *Wrapper) IsNotNull(column string) *Wrapper {
w.db = w.db.Where(column + " IS NOT NULL")
return w
}

// Joins 连接查询
func (w *Wrapper) Joins(query string, args ...interface{}) *Wrapper {
w.db = w.db.Joins(query, args...)
return w
}

// Find 查询
func (w *Wrapper) Find(dest interface{}) error {
return w.db.Find(dest).Error
}

// First 查询第一条
func (w *Wrapper) First(dest interface{}) error {
return w.db.First(dest).Error
}

// Count 统计
func (w *Wrapper) Count(count *int64) error {
return w.db.Count(count).Error
}

// Build 构建查询
func (w *Wrapper) Build() func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where(w.db.Statement.Clauses["WHERE"].Expression)
}
}

// Clone 克隆当前 Wrapper
func (w *Wrapper) Clone() *Wrapper {
return &Wrapper{db: w.db.Session(&gorm.Session{})}
}

// WithContext 设置上下文
func (w *Wrapper) WithContext(ctx context.Context) *Wrapper {
w.db = w.db.WithContext(ctx)
return w
}

// Transaction 添加事务
func (w *Wrapper) Transaction(fn func(tx *Wrapper) error) error {
return w.db.Transaction(func(tx *gorm.DB) error {
txWrapper := &Wrapper{db: tx}
return fn(txWrapper)
})
}

// Scan 扫描结果到目标
func (w *Wrapper) Scan(dest any) error {
return w.db.Scan(dest).Error
}

// Prepare 预编译 SQL 语句
func (w *Wrapper) Prepare() *Wrapper {
w.db = w.db.Session(&gorm.Session{PrepareStmt: true})
return w
}

// Select 仅选择需要的字段
func (w *Wrapper) Select(fields ...string) *Wrapper {
w.db = w.db.Select(fields)
return w
}
package db

import (
"context"
"errors"

"gorm.io/gorm"
"gorm.io/gorm/clause"
)

type Dao[T any] interface {
//Save 保存
Save(ctx context.Context, model *T) error
// Create 添加
Create(ctx context.Context, model *T) error
// CreateOrUpdate 批量添加或更新
CreateOrUpdate(ctx context.Context, model *T) error
// CreateBatch 批量添加
CreateBatch(ctx context.Context, models []T) error
// CreateBatchSize 批量添加指定大小
CreateBatchSize(ctx context.Context, models []T, size int) error
// Update 更新
Update(ctx context.Context, condition, model *T) error
//UpdaterWrapper 更新
UpdaterWrapper(ctx context.Context, wrapper *Wrapper, model *T) error
// GetByID 根据 ID 获取
GetByID(ctx context.Context, ID any) (*T, error)
// GetByCondition 根据条件获取
GetByCondition(ctx context.Context, condition T) (*T, error)
//GetByWrapper 根据条件获取
GetByWrapper(ctx context.Context, wrapper *Wrapper) (*T, error)
// Page 分页查询
Page(ctx context.Context, page, size int) ([]T, int64, error)
// PageByCondition 分页查询
PageByCondition(ctx context.Context, page, size int, condition *T) ([]T, int64, error)
// PageByWrapper 分页查询
PageByWrapper(ctx context.Context, page, size int, wrapper *Wrapper) ([]T, int64, error)
//ListByCondition 根据条件获取多个
ListByCondition(ctx context.Context, condition T) ([]T, error)
// ListByWrapper 根据条件获取多个
ListByWrapper(ctx context.Context, wrapper *Wrapper) ([]T, error)
// Count 统计数量
Count(ctx context.Context) (int64, error)
// CountByWrapper 统计数量
CountByWrapper(ctx context.Context, wrapper *Wrapper) (int64, error)
// Delete 删除
Delete(ctx context.Context, value any) error
//DeleteByWrapper 删除
DeleteByWrapper(ctx context.Context, wrapper *Wrapper) error
}

type Curd[T any] struct {
model T
}

// Save 保存
func (c *Curd[T]) Save(ctx context.Context, model *T) error {
return DB().Model(&c.model).WithContext(ctx).Save(&model).Error
}

// Create 添加
func (c *Curd[T]) Create(ctx context.Context, model *T) error {
err := DB().Model(&c.model).WithContext(ctx).Create(&model).Error
if err != nil {
if errors.Is(err, gorm.ErrDuplicatedKey) {
return errors.New("record already exists")
}
return err
}
return nil
}

// CreateOrUpdate 添加或更新
func (c *Curd[T]) CreateOrUpdate(ctx context.Context, model *T) error {
err := DB().Model(&c.model).WithContext(ctx).Clauses(clause.OnConflict{
UpdateAll: true,
}).Create(&model).Error
if err != nil {
if errors.Is(err, gorm.ErrDuplicatedKey) {
return errors.New("record already exists")
}
return err
}
return nil
}

// CreateBatch 批量添加
func (c *Curd[T]) CreateBatch(ctx context.Context, models []T) error {
err := DB().Model(&c.model).WithContext(ctx).Create(&models).Error
if err != nil {
if errors.Is(err, gorm.ErrDuplicatedKey) {
return errors.New("数据重复")
}
return err
}
return nil
}

// CreateBatchSize 批量添加指定大小
func (c *Curd[T]) CreateBatchSize(ctx context.Context, models []T, size int) error {
err := DB().Model(&c.model).WithContext(ctx).CreateInBatches(&models, size).Error
if err != nil {
if errors.Is(err, gorm.ErrDuplicatedKey) {
return errors.New("数据重复")
}
return err
}
return nil
}

// Update 更新 传入的 model 必须包含主键
func (c *Curd[T]) Update(ctx context.Context, condition, model *T) error {
err := DB().Model(&model).WithContext(ctx).Updates(&model).Where(&condition).Error
if err != nil {
if errors.Is(err, gorm.ErrDuplicatedKey) {
return errors.New("数据重复")
}
return err
}
return nil
}

// UpdaterWrapper 根据构造器更新
func (c *Curd[T]) UpdaterWrapper(ctx context.Context, wrapper *Wrapper, model *T) error {
err := DB().Model(&model).WithContext(ctx).Scopes(wrapper.Build()).Updates(&model).Error
if err != nil {
if errors.Is(err, gorm.ErrDuplicatedKey) {
return errors.New("数据重复")
}
return err
}
return nil
}

// Delete 删除 value 可以为单个主键或者多个主键切片
func (c *Curd[T]) Delete(ctx context.Context, value any) error {
return DB().Model(&c.model).WithContext(ctx).Delete(&c.model, value).Error
}

// DeleteByWrapper 根据构造器删除
func (c *Curd[T]) DeleteByWrapper(ctx context.Context, wrapper *Wrapper) error {
return DB().Model(&c.model).WithContext(ctx).Scopes(wrapper.Build()).Delete(&c.model).Error
}

// GetByID 根据 ID 获取
func (c *Curd[T]) GetByID(ctx context.Context, ID any) (*T, error) {
var model T
err := DB().Model(&c.model).WithContext(ctx).Take(&model, ID).Error
if err != nil {
return nil, err
}
return &model, nil
}

// GetByCondition 根据条件获取
func (c *Curd[T]) GetByCondition(ctx context.Context, condition *T) (*T, error) {
var model T
err := DB().Model(&c.model).WithContext(ctx).Where(&condition).Take(&model).Error
if err != nil {
return nil, err
}
return &model, nil
}

// GetByWrapper 根据构造条件获取
func (c *Curd[T]) GetByWrapper(ctx context.Context, wrapper *Wrapper) (*T, error) {
var model T
err := DB().Model(&c.model).WithContext(ctx).Scopes(wrapper.Build()).Take(&model).Error
if err != nil {
return nil, err
}
return &model, nil
}

// Page 分页查询
func (c *Curd[T]) Page(ctx context.Context, page, size int) (models []T, total int64, err error) {
models = make([]T, 0)
if err = DB().Model(&c.model).WithContext(ctx).Count(&total).Scopes(Page(page, size)).Find(&models).Error; err != nil {
return models, 0, err
}
return models, total, nil
}

// PageByCondition 分页查询 根据条件
func (c *Curd[T]) PageByCondition(ctx context.Context, page, size int, condition *T) (models []T, total int64, err error) {
models = make([]T, 0)
if err = DB().Model(&c.model).WithContext(ctx).Where(&condition).Count(&total).Scopes(Page(page, size)).Find(&models).Error; err != nil {
return models, 0, err
}
return models, total, nil
}

// PageByWrapper 分页查询 根据构造器
func (c *Curd[T]) PageByWrapper(ctx context.Context, page, size int, wrapper *Wrapper) (models []T, total int64, err error) {
models = make([]T, 0)
err = DB().WithContext(ctx).Scopes(wrapper.Build()).Count(&total).Scopes(Page(page, size)).Find(&models).Error
if err != nil {
return models, 0, err
}
return models, total, nil
}

// ListByCondition 根据条件获取多个
func (c *Curd[T]) ListByCondition(ctx context.Context, condition *T) ([]T, error) {
models := make([]T, 0)
err := DB().Model(&c.model).WithContext(ctx).Where(&condition).Find(&models).Error
if err != nil {
return models, err
}
return models, nil
}

// ListByWrapper 根据构造器获取多个
func (c *Curd[T]) ListByWrapper(ctx context.Context, wrapper *Wrapper) (models []T, err error) {
models = make([]T, 0)
err = DB().Model(&c.model).WithContext(ctx).Scopes(wrapper.Build()).Find(&models).Error
if err != nil {
return models, err
}
return models, nil
}

// Count 统计数量
func (c *Curd[T]) Count(ctx context.Context) (total int64, err error) {
if err = DB().WithContext(ctx).Model(&c.model).Count(&total).Error; err != nil {
return 0, err
}
return total, nil
}

// CountByWrapper 统计数量 根据构造器
func (c *Curd[T]) CountByWrapper(ctx context.Context, wrapper *Wrapper) (total int64, err error) {
if err = DB().WithContext(ctx).Scopes(wrapper.Build()).Count(&total).Error; err != nil {
return 0, err
}
return total, nil
}





//用例
type memberDao struct {
db.Curd[model.Member]
}
88 天前
回复了 kuanat 创建的主题 Go 编程语言 Go 语言的错误处理语法,不改了!
@htxy1985 深色模式
Bark
160 天前
回复了 cxhello 创建的主题 Go 编程语言 Go 框架使用调研
一般项目用 gin ,高要求可以用字节的 hertz
我目前手上用 M1 8+256 用 flutter 开发安卓和 iOS ,编译也不慢
302 天前
回复了 Corey0606 创建的主题 Apple 请教大佬 mac mini4 丐版配件怎么选?
问一下,您远程用的方案是?
2024-08-24 23:25:08 +08:00
回复了 missx 创建的主题 微信 微信现在有什么办法强制加好友
/t/925567
你好可怕,太恐怖了,女孩子怎么就碰上你这么个变态,别研究强制加好友了,研究时光倒流吧。
2024-07-31 19:57:52 +08:00
回复了 SillyGod 创建的主题 问与答 日版 iPhone 有无推荐店铺
倒爷 家的不错,淘宝店,可以看看
2024-07-26 11:32:45 +08:00
回复了 zhoust 创建的主题 商业模式 日入 5000+,有点无法理解这个世界了
@zhoust 楼上
2024-07-26 11:32:00 +08:00
回复了 zhoust 创建的主题 商业模式 日入 5000+,有点无法理解这个世界了
想了解一下硬件,OP 可否加个 b64s:SU9CVUZG
@delai 用啥技术开发的,知道吗?
2024-06-28 22:35:31 +08:00
回复了 Jack66 创建的主题 Go 编程语言 golang 大家微服务都是什么方案?
单体 YYDS
2024-06-03 20:01:45 +08:00
回复了 Wikey 创建的主题 职场话题 普通人还能达到雷军、卢伟冰那样的成长曲线吗
@lesismal 在用大佬的 nbio
2024-05-10 11:28:11 +08:00
回复了 ievjai 创建的主题 程序员 我创建了「信息技术群」,不交流,只是围观
SU9CVUZG
2024-04-23 22:45:06 +08:00
回复了 unt 创建的主题 程序员 请问有没有好用的 Go MQTT Broker
2024-04-18 23:47:23 +08:00
回复了 idblife 创建的主题 Go 编程语言 gin 的用户验证,用户组这些都要自己实现吗?
gin 只是一个 web 框架,web 框架就是给你实现路由匹配、参数绑定、序列化、反序列化这些功能
gin
2024-04-03 23:43:48 +08:00
回复了 dululu 创建的主题 优惠信息 你有不为人知的省钱小妙招吗?
@a1b2c3T 在闲鱼干啥都行,就是不要交电费
2024-03-27 14:29:02 +08:00
回复了 luzemin 创建的主题 程序员 HackerNews 上看到的 [丑丑头像生成器]
nice
1  2  3  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1456 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 33ms · UTC 16:50 · PVG 00:50 · LAX 09:50 · JFK 12:50
Developed with CodeLauncher
♥ Do have faith in what you're doing.