database/base.go

284 lines
6.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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)
}
}
// 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])
}
// 排序
for _, orderRule := range o.Order {
tx = tx.Order(orderRule)
}
// 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
}