288 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Package database ...
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 8:04 下午 2021/8/8
 | 
						||
package database
 | 
						||
 | 
						||
import (
 | 
						||
	"errors"
 | 
						||
	"git.zhangdeman.cn/zhangdeman/database/define"
 | 
						||
 | 
						||
	"gorm.io/gorm"
 | 
						||
)
 | 
						||
 | 
						||
// BaseDao 基础dao层
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 14:13 2023/2/9
 | 
						||
type BaseDao struct {
 | 
						||
	TableName string // 继承BaseDao,需要指定表名,后续调用不用传递表名进来,如果分表了,使用SetOption设置表名, 这里的优先级更高
 | 
						||
}
 | 
						||
 | 
						||
// Create 创建新的数据
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 8:06 下午 2021/8/8
 | 
						||
func (b *BaseDao) Create(dbInstance *gorm.DB, data any, optionList ...define.SetOption) error {
 | 
						||
	o := &define.Option{}
 | 
						||
	for _, itemFunc := range optionList {
 | 
						||
		itemFunc(o)
 | 
						||
	}
 | 
						||
	tableName := b.TableName
 | 
						||
	if len(o.Table) > 0 {
 | 
						||
		tableName = o.Table
 | 
						||
	}
 | 
						||
	return dbInstance.Table(tableName).Create(data).Error
 | 
						||
}
 | 
						||
 | 
						||
// Update 更新数据
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 8:12 下午 2021/8/8
 | 
						||
func (b *BaseDao) Update(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) {
 | 
						||
	dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
 | 
						||
	r := dbInstance.Updates(updateData)
 | 
						||
	return r.RowsAffected, r.Error
 | 
						||
}
 | 
						||
 | 
						||
// UpdateOne 更新一条数据
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 17:05 2024/1/13
 | 
						||
func (b *BaseDao) UpdateOne(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) {
 | 
						||
	optionFuncList = append(optionFuncList, WithLimit(1, 0))
 | 
						||
	return b.Update(dbInstance, updateData, optionFuncList...)
 | 
						||
}
 | 
						||
 | 
						||
// List 查询数据列表
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 8:14 下午 2021/8/8
 | 
						||
func (b *BaseDao) List(dbInstance *gorm.DB, result any, optionFuncList ...define.SetOption) error {
 | 
						||
	dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
 | 
						||
	return dbInstance.Find(result).Error
 | 
						||
}
 | 
						||
 | 
						||
// Delete 删除数据, 硬删除, 对应 delete语句
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 11:46 2023/2/9
 | 
						||
func (b *BaseDao) Delete(dbInstance *gorm.DB, dataModel any, optionFuncList ...define.SetOption) (int64, error) {
 | 
						||
	dbInstance = dbInstance.Model(dataModel)
 | 
						||
	dbInstance = b.setTxCondition(dbInstance, optionFuncList...).Delete(dataModel)
 | 
						||
	return dbInstance.RowsAffected, dbInstance.Error
 | 
						||
}
 | 
						||
 | 
						||
// Detail 查询详情
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 8:25 下午 2021/8/8
 | 
						||
func (b *BaseDao) Detail(dbInstance *gorm.DB, result any, optionFuncList ...define.SetOption) error {
 | 
						||
	dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
 | 
						||
	return dbInstance.First(result).Error
 | 
						||
}
 | 
						||
 | 
						||
// DetailByPrimaryID ...
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 14:14 2023/10/15
 | 
						||
func (b *BaseDao) DetailByPrimaryID(dbInstance *gorm.DB, result any, primaryID any, primaryKey ...string) error {
 | 
						||
	primaryKeyField := "id"
 | 
						||
	if len(primaryKey) > 0 {
 | 
						||
		primaryKeyField = primaryKey[0]
 | 
						||
	}
 | 
						||
	return b.Detail(dbInstance, result, WithWhere(map[string]any{
 | 
						||
		primaryKeyField: primaryID,
 | 
						||
	}))
 | 
						||
}
 | 
						||
 | 
						||
// IsNotFound 增加结果是否为数据不存在的判断
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 15:57 2023/2/23
 | 
						||
func (b *BaseDao) IsNotFound(err error) bool {
 | 
						||
	return errors.Is(err, gorm.ErrRecordNotFound)
 | 
						||
}
 | 
						||
 | 
						||
// Count 查询数量
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 8:25 下午 2021/8/8
 | 
						||
func (b *BaseDao) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) (int64, error) {
 | 
						||
	dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
 | 
						||
	var cnt int64
 | 
						||
	return cnt, dbInstance.Count(&cnt).Error
 | 
						||
}
 | 
						||
 | 
						||
// Tx 执行事务
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 20:31 2022/12/24
 | 
						||
func (b *BaseDao) Tx(dbInstance *gorm.DB, txFunc func(dbInstance *gorm.DB) error) error {
 | 
						||
	if nil == dbInstance {
 | 
						||
		return errors.New("db instance is null")
 | 
						||
	}
 | 
						||
	tx := b.Begin(dbInstance)
 | 
						||
	if err := txFunc(tx); nil != err {
 | 
						||
		_ = b.Rollback(tx)
 | 
						||
		return err
 | 
						||
	}
 | 
						||
	return b.Commit(tx)
 | 
						||
}
 | 
						||
 | 
						||
// Begin 开启事务
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 3:09 下午 2021/8/9
 | 
						||
func (b *BaseDao) Begin(dbInstance *gorm.DB) *gorm.DB {
 | 
						||
	return dbInstance.Begin()
 | 
						||
}
 | 
						||
 | 
						||
// Commit 提交事务
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 3:10 下午 2021/8/9
 | 
						||
func (b *BaseDao) Commit(db *gorm.DB) error {
 | 
						||
	return db.Commit().Error
 | 
						||
}
 | 
						||
 | 
						||
// Rollback 回滚
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 3:12 下午 2021/8/9
 | 
						||
func (b *BaseDao) Rollback(db *gorm.DB) error {
 | 
						||
	return db.Rollback().Error
 | 
						||
}
 | 
						||
 | 
						||
// setTxCondition 设置查询条件
 | 
						||
//
 | 
						||
// Author : go_developer@163.com<白茶清欢>
 | 
						||
//
 | 
						||
// Date : 17:38 2022/5/15
 | 
						||
func (b *BaseDao) setTxCondition(tx *gorm.DB, optionFuncList ...define.SetOption) *gorm.DB {
 | 
						||
 | 
						||
	// 构建查询条件
 | 
						||
	o := &define.Option{}
 | 
						||
	for _, fn := range optionFuncList {
 | 
						||
		fn(o)
 | 
						||
	}
 | 
						||
 | 
						||
	// 指定查询的表
 | 
						||
	if len(o.Table) > 0 {
 | 
						||
		tx = tx.Table(o.Table)
 | 
						||
	} else {
 | 
						||
		tx = tx.Table(b.TableName)
 | 
						||
	}
 | 
						||
 | 
						||
	if nil != o.Model {
 | 
						||
		tx = tx.Model(o.Model)
 | 
						||
	}
 | 
						||
 | 
						||
	// 设置 limit offset
 | 
						||
	if o.Limit > 0 {
 | 
						||
		tx = tx.Limit(o.Limit)
 | 
						||
		if o.Offset >= 0 {
 | 
						||
			tx = tx.Offset(o.Offset)
 | 
						||
		}
 | 
						||
	}
 | 
						||
	// in 语句
 | 
						||
	if nil != o.In {
 | 
						||
		tx = tx.Where(o.In)
 | 
						||
	}
 | 
						||
 | 
						||
	// not in 语句
 | 
						||
	if nil != o.NotIn {
 | 
						||
		for field, value := range o.NotIn {
 | 
						||
			tx = tx.Where(field+" NOT IN ? ", value)
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// like 语句
 | 
						||
	if nil != o.Like {
 | 
						||
		for field, value := range o.Like {
 | 
						||
			tx = tx.Where(field+" LIKE ? ", "%"+value+"%")
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// NOT LIKE 语句
 | 
						||
	if nil != o.NotLike {
 | 
						||
		for field, value := range o.NotLike {
 | 
						||
			tx = tx.Where(field+" NOT LIKE ? ", "%"+value+"%")
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// >=
 | 
						||
	if nil != o.Start {
 | 
						||
		for field, value := range o.Start {
 | 
						||
			tx = tx.Where(field+" >= ?", value)
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// <
 | 
						||
	if nil != o.End {
 | 
						||
		for field, value := range o.End {
 | 
						||
			tx = tx.Where(field+" < ?", value)
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	if len(o.Where) > 0 {
 | 
						||
		tx = tx.Where(o.Where)
 | 
						||
	}
 | 
						||
 | 
						||
	// between
 | 
						||
	for field, betweenVal := range o.Between {
 | 
						||
		tx = tx.Where("`"+field+"` BETWEEN ? AND ?", betweenVal[0], betweenVal[1])
 | 
						||
	}
 | 
						||
	// not between
 | 
						||
	for field, notBetweenVal := range o.NotBetween {
 | 
						||
		tx = tx.Where("`"+field+"` NOT BETWEEN ? AND ?", notBetweenVal[0], notBetweenVal[1])
 | 
						||
	}
 | 
						||
 | 
						||
	// 排序
 | 
						||
	if len(o.Order) == 2 {
 | 
						||
		tx = tx.Order(o.Order[0] + " " + o.Order[1])
 | 
						||
	}
 | 
						||
 | 
						||
	// or 语句
 | 
						||
	if nil != o.OR {
 | 
						||
		for _, itemOr := range o.OR {
 | 
						||
			orOption := &define.Option{}
 | 
						||
			for _, fn := range itemOr {
 | 
						||
				fn(orOption)
 | 
						||
			}
 | 
						||
			orSql, orBindVal := optionToSql(orOption)
 | 
						||
			tx.Or(orSql, orBindVal)
 | 
						||
		}
 | 
						||
	}
 | 
						||
	/*sqlBlockList := make([]string, 0)
 | 
						||
	bindValueList := make([]any, 0)
 | 
						||
	sql, bindVal := optionToSql(o)
 | 
						||
	tx.Or(sql, bindVal...)
 | 
						||
	sqlBlockList = append(sqlBlockList, sql)
 | 
						||
	bindValueList = append(bindValueList, bindVal)
 | 
						||
	for _, itemOrFuncList := range o.OR {
 | 
						||
		orOption := &Option{}
 | 
						||
		for _, fn := range itemOrFuncList {
 | 
						||
			fn(orOption)
 | 
						||
		}
 | 
						||
		orSql, orBindVal := optionToSql(orOption)
 | 
						||
		tx.Or(orSql, orBindVal...)
 | 
						||
	}*/
 | 
						||
	return tx
 | 
						||
}
 |