database/base.go

288 lines
6.8 KiB
Go
Raw Normal View History

2023-04-18 18:25:39 +08:00
// Package database ...
2022-05-15 11:27:28 +08:00
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:04 下午 2021/8/8
2023-04-18 18:25:39 +08:00
package database
2022-05-15 11:27:28 +08:00
2022-05-15 18:04:06 +08:00
import (
2022-12-24 21:37:08 +08:00
"errors"
2024-08-23 17:54:48 +08:00
"git.zhangdeman.cn/zhangdeman/database/define"
2023-02-09 11:51:55 +08:00
2022-05-15 18:04:06 +08:00
"gorm.io/gorm"
)
2022-05-15 11:27:28 +08:00
2023-02-09 14:21:26 +08:00
// BaseDao 基础dao层
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:13 2023/2/9
2022-05-15 11:27:28 +08:00
type BaseDao struct {
2023-04-06 22:12:35 +08:00
TableName string // 继承BaseDao需要指定表名后续调用不用传递表名进来如果分表了使用SetOption设置表名, 这里的优先级更高
2022-05-15 11:27:28 +08:00
}
2022-05-15 18:30:08 +08:00
// Create 创建新的数据
2022-05-15 11:27:28 +08:00
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:06 下午 2021/8/8
2024-08-23 17:54:48 +08:00
func (b *BaseDao) Create(dbInstance *gorm.DB, data any, optionList ...define.SetOption) error {
o := &define.Option{}
2023-04-06 22:12:35 +08:00
for _, itemFunc := range optionList {
itemFunc(o)
}
tableName := b.TableName
if len(o.Table) > 0 {
tableName = o.Table
}
return dbInstance.Table(tableName).Create(data).Error
2022-05-15 11:27:28 +08:00
}
2022-05-15 18:30:08 +08:00
// Update 更新数据
2022-05-15 11:27:28 +08:00
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:12 下午 2021/8/8
2024-08-23 17:54:48 +08:00
func (b *BaseDao) Update(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) {
2023-02-09 14:21:26 +08:00
dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
2023-10-13 22:16:48 +08:00
r := dbInstance.Updates(updateData)
return r.RowsAffected, r.Error
2022-05-15 11:27:28 +08:00
}
2024-01-13 17:08:47 +08:00
// UpdateOne 更新一条数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:05 2024/1/13
2024-08-23 17:54:48 +08:00
func (b *BaseDao) UpdateOne(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) {
2024-01-13 17:08:47 +08:00
optionFuncList = append(optionFuncList, WithLimit(1, 0))
return b.Update(dbInstance, updateData, optionFuncList...)
}
2022-05-15 18:30:08 +08:00
// List 查询数据列表
2022-05-15 11:27:28 +08:00
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:14 下午 2021/8/8
2024-08-23 17:54:48 +08:00
func (b *BaseDao) List(dbInstance *gorm.DB, result any, optionFuncList ...define.SetOption) error {
2023-02-09 14:21:26 +08:00
dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
2023-03-22 21:02:24 +08:00
return dbInstance.Find(result).Error
2022-05-15 11:27:28 +08:00
}
2023-02-09 11:51:55 +08:00
// Delete 删除数据, 硬删除, 对应 delete语句
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:46 2023/2/9
2024-08-23 17:54:48 +08:00
func (b *BaseDao) Delete(dbInstance *gorm.DB, dataModel any, optionFuncList ...define.SetOption) (int64, error) {
2024-01-15 15:30:15 +08:00
dbInstance = dbInstance.Model(dataModel)
2023-03-22 21:02:24 +08:00
dbInstance = b.setTxCondition(dbInstance, optionFuncList...).Delete(dataModel)
2023-03-19 12:46:22 +08:00
return dbInstance.RowsAffected, dbInstance.Error
2023-02-09 11:51:55 +08:00
}
2022-05-15 11:27:28 +08:00
// Detail 查询详情
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:25 下午 2021/8/8
2024-08-23 17:54:48 +08:00
func (b *BaseDao) Detail(dbInstance *gorm.DB, result any, optionFuncList ...define.SetOption) error {
2023-02-09 14:21:26 +08:00
dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
2023-03-22 21:02:24 +08:00
return dbInstance.First(result).Error
2022-05-15 11:27:28 +08:00
}
2023-10-15 14:15:03 +08:00
// DetailByPrimaryID ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:14 2023/10/15
2024-08-09 17:17:20 +08:00
func (b *BaseDao) DetailByPrimaryID(dbInstance *gorm.DB, result any, primaryID any, primaryKey ...string) error {
2023-10-15 14:15:03 +08:00
primaryKeyField := "id"
if len(primaryKey) > 0 {
primaryKeyField = primaryKey[0]
}
2024-08-09 17:17:20 +08:00
return b.Detail(dbInstance, result, WithWhere(map[string]any{
2023-10-15 14:15:03 +08:00
primaryKeyField: primaryID,
}))
}
// IsNotFound 增加结果是否为数据不存在的判断
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:57 2023/2/23
func (b *BaseDao) IsNotFound(err error) bool {
2023-10-14 15:14:05 +08:00
return errors.Is(err, gorm.ErrRecordNotFound)
}
2022-05-15 11:27:28 +08:00
// Count 查询数量
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:25 下午 2021/8/8
2024-08-23 17:54:48 +08:00
func (b *BaseDao) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) (int64, error) {
2023-02-09 14:21:26 +08:00
dbInstance = b.setTxCondition(dbInstance, optionFuncList...)
2022-05-15 11:27:28 +08:00
var cnt int64
2023-03-22 21:02:24 +08:00
return cnt, dbInstance.Count(&cnt).Error
2022-05-15 11:27:28 +08:00
}
2022-12-24 21:37:08 +08:00
// 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)
}
2022-05-15 11:27:28 +08:00
// 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
}
2022-05-15 18:04:06 +08:00
// setTxCondition 设置查询条件
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:38 2022/5/15
2024-08-23 17:54:48 +08:00
func (b *BaseDao) setTxCondition(tx *gorm.DB, optionFuncList ...define.SetOption) *gorm.DB {
2022-05-15 18:04:06 +08:00
// 构建查询条件
2024-08-23 17:54:48 +08:00
o := &define.Option{}
2022-05-15 18:04:06 +08:00
for _, fn := range optionFuncList {
fn(o)
}
2023-03-22 21:02:24 +08:00
// 指定查询的表
if len(o.Table) > 0 {
2023-10-08 21:36:39 +08:00
tx = tx.Table(o.Table)
2023-03-22 21:02:24 +08:00
} else {
tx = tx.Table(b.TableName)
}
2024-01-15 15:20:27 +08:00
if nil != o.Model {
tx = tx.Model(o.Model)
}
2022-05-15 18:04:06 +08:00
// 设置 limit offset
if o.Limit > 0 {
2022-07-19 12:17:26 +08:00
tx = tx.Limit(o.Limit)
2024-05-08 14:36:30 +08:00
if o.Offset >= 0 {
tx = tx.Offset(o.Offset)
}
2022-05-15 18:04:06 +08:00
}
// 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)
}
}
2024-08-24 13:23:37 +08:00
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])
}
// 排序
2024-09-20 16:43:03 +08:00
if len(o.Order) == 2 {
tx = tx.Order(o.Order[0] + " " + o.Order[1])
}
// or 语句
if nil != o.OR {
for _, itemOr := range o.OR {
2024-08-23 17:54:48 +08:00
orOption := &define.Option{}
for _, fn := range itemOr {
fn(orOption)
}
orSql, orBindVal := optionToSql(orOption)
tx.Or(orSql, orBindVal)
}
}
/*sqlBlockList := make([]string, 0)
2024-08-09 18:26:30 +08:00
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)
2022-05-15 18:04:06 +08:00
}
2024-08-09 18:26:30 +08:00
orSql, orBindVal := optionToSql(orOption)
tx.Or(orSql, orBindVal...)
}*/
2022-07-19 12:17:26 +08:00
return tx
2022-05-15 18:04:06 +08:00
}