gf icon indicating copy to clipboard operation
gf copied to clipboard

When using the soft delete function for plastic shaping timestamp, how to change the query condition to deleted_at is NULL

Open minxinqing opened this issue 7 months ago • 3 comments

What do you want to ask?

我们数据库中的时间戳字段是int型,在使用gf v2.8.3时,orm生成的查询条件where deleted_at = 0,但是我们库中未删除记录默认值是null,导致查询不到数据。 我想知道deleted_at字段为int时,生成的查询条件怎么改成 deleted_at is null?

minxinqing avatar May 14 '25 04:05 minxinqing

能否给出示例代码,以及建表sql?

听上去像一个 bug。

wufeng5702 avatar May 29 '25 08:05 wufeng5702

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Can you give example code and create table sql?

It sounds like a bug.

Issues-translate-bot avatar May 29 '25 08:05 Issues-translate-bot

能否给出示例代码,以及建表sql?

听上去像一个 bug。

CREATE TABLE user ( id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(45) NOT NULL, status tinyint DEFAULT 0, created_at int(10) unsigned DEFAULT NULL, updated_at int(10) unsigned DEFAULT NULL, deleted_at int(10) unsigned DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

像这种情况,怎么改成查询条件deleted_at=null,而不是deleted_at=0?

CasperCC avatar Jun 16 '25 16:06 CasperCC

能否给出示例代码,以及建表sql? 听上去像一个 bug。

CREATE TABLE user ( id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(45) NOT NULL, status tinyint DEFAULT 0, created_at int(10) unsigned DEFAULT NULL, updated_at int(10) unsigned DEFAULT NULL, deleted_at int(10) unsigned DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

像这种情况,怎么改成查询条件deleted_at=null,而不是deleted_at=0?

原来是这个需求,文档中有提到:时间维护-SoftTimeOption

相关源码: https://github.com/gogf/gf/blob/88c44715002c95016fbbed954ab4a633c0f30ff7/database/gdb/gdb_model_soft_time.go#L343-L375

这里很关键:

// 如果是配置的选项是 SoftTimeTypeTime, 生成 `field IS NULL` 的查询条件
case SoftTimeTypeTime:
	return fmt.Sprintf(`%s IS NULL`, quotedFieldName)

引入这个配置选项的方法: https://github.com/gogf/gf/blob/88c44715002c95016fbbed954ab4a633c0f30ff7/database/gdb/gdb_model_soft_time.go#L85-L90

为了方便使用,你可以配置 dao 层的实例化的选项:

package dao

import (
	"issue/4280/internal/dao/internal"

	"github.com/gogf/gf/v2/database/gdb"
)

// userDao is the data access object for the table user.
// You can define custom methods on it to extend its functionality as needed.
type userDao struct {
	*internal.UserDao
}

var (
	// User is a globally accessible object for table user operations.
	User = userDao{internal.NewUserDao(
		func(m *gdb.Model) *gdb.Model {
			return m.SoftTime(gdb.SoftTimeOption{
				SoftTimeType: gdb.SoftTimeTypeTime,
			})
		},
	)}
)

如果修改的文件很多,你可以通过参数 --tplDaoIndexPath 导入自己的模板文件:

Image

wufeng5702 avatar Jun 17 '25 12:06 wufeng5702

能否给出示例代码,以及建表sql? 听上去像一个 bug。

CREATE TABLE user ( id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(45) NOT NULL, status tinyint DEFAULT 0, created_at int(10) unsigned DEFAULT NULL, updated_at int(10) unsigned DEFAULT NULL, deleted_at int(10) unsigned DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 像这种情况,怎么改成查询条件deleted_at=null,而不是deleted_at=0?

原来是这个需求,文档中有提到:时间维护-SoftTimeOption

相关源码:

gf/database/gdb/gdb_model_soft_time.go

Lines 343 to 375 in 88c4471

func (m *softTimeMaintainer) getConditionByFieldNameAndTypeForSoftDeleting( ctx context.Context, fieldPrefix, fieldName string, fieldType LocalType, ) string { var ( quotedFieldPrefix = m.db.GetCore().QuoteWord(fieldPrefix) quotedFieldName = m.db.GetCore().QuoteWord(fieldName) ) if quotedFieldPrefix != "" { quotedFieldName = fmt.Sprintf(%s.%s, quotedFieldPrefix, quotedFieldName) } switch m.softTimeOption.SoftTimeType { case SoftTimeTypeAuto: switch fieldType { case LocalTypeDate, LocalTypeTime, LocalTypeDatetime: return fmt.Sprintf(%s IS NULL, quotedFieldName) case LocalTypeInt, LocalTypeUint, LocalTypeInt64, LocalTypeUint64, LocalTypeBool: return fmt.Sprintf(%s=0, quotedFieldName) default: intlog.Errorf( ctx, invalid field type "%s" of field name "%s" with prefix "%s" for soft deleting condition, fieldType, fieldName, fieldPrefix, ) }

case SoftTimeTypeTime: return fmt.Sprintf(%s IS NULL, quotedFieldName)

default: return fmt.Sprintf(%s=0, quotedFieldName) } return "" } 这里很关键:

// 如果是配置的选项是 SoftTimeTypeTime, 生成 field IS NULL 的查询条件 case SoftTimeTypeTime: return fmt.Sprintf(%s IS NULL, quotedFieldName) 引入这个配置选项的方法:

gf/database/gdb/gdb_model_soft_time.go

Lines 85 to 90 in 88c4471

// SoftTime sets the SoftTimeOption to customize soft time feature for Model. func (m *Model) SoftTime(option SoftTimeOption) *Model { model := m.getModel() model.softTimeOption = option return model } 为了方便使用,你可以配置 dao 层的实例化的选项:

package dao

import ( "issue/4280/internal/dao/internal"

"github.com/gogf/gf/v2/database/gdb" )

// userDao is the data access object for the table user. // You can define custom methods on it to extend its functionality as needed. type userDao struct { *internal.UserDao }

var ( // User is a globally accessible object for table user operations. User = userDao{internal.NewUserDao( func(m *gdb.Model) *gdb.Model { return m.SoftTime(gdb.SoftTimeOption{ SoftTimeType: gdb.SoftTimeTypeTime, }) }, )} ) 如果修改的文件很多,你可以通过参数 --tplDaoIndexPath 导入自己的模板文件:

Image

明白了,确实有用,谢谢!

CasperCC avatar Jun 17 '25 14:06 CasperCC