feat(repository): enhance repository methods with batch processing and transaction support
All checks were successful
Build Backend / build (push) Successful in 12m50s
Build Backend / build-docker (push) Successful in 2m57s

- Updated Like and Unlike methods in CommentRepository to use transactions for data consistency.
- Introduced IsLikedBatch method for batch checking if comments are liked, addressing N+1 query issues.
- Enhanced BatchDelete method in PostRepository to perform batch deletions within a single transaction, improving efficiency.
- Added BatchUpdateStatus method for posts to utilize a single SQL update for status changes, reducing database load.
- Implemented BatchUpdateSortOrder in StickerRepository using CASE WHEN for efficient sorting updates.
- Added IsFollowingBatch and IsBlockedBatch methods in UserRepository for batch checking follow and block relationships, optimizing performance.
This commit is contained in:
lafay
2026-03-26 01:50:54 +08:00
parent 56bd971e42
commit 7b41dfeb00
9 changed files with 386 additions and 109 deletions

View File

@@ -17,21 +17,24 @@ func NewVoteRepository(db *gorm.DB) *VoteRepository {
return &VoteRepository{db: db}
}
// CreateOptions 批量创建投票选项
// CreateOptions 批量创建投票选项(使用批量插入,避免 N+1 问题)
func (r *VoteRepository) CreateOptions(postID string, options []string) error {
return r.db.Transaction(func(tx *gorm.DB) error {
for i, content := range options {
option := &model.VoteOption{
PostID: postID,
Content: content,
SortOrder: i,
}
if err := tx.Create(option).Error; err != nil {
return err
}
}
if len(options) == 0 {
return nil
})
}
// 构建批量插入的选项切片
voteOptions := make([]model.VoteOption, len(options))
for i, content := range options {
voteOptions[i] = model.VoteOption{
PostID: postID,
Content: content,
SortOrder: i,
}
}
// 使用 GORM 的 Create 方法批量插入
return r.db.CreateInBatches(voteOptions, 100).Error
}
// GetOptionsByPostID 获取帖子的所有投票选项
@@ -58,9 +61,9 @@ func (r *VoteRepository) Vote(postID, userID, optionID string) error {
// 验证选项是否属于该帖子
var option model.VoteOption
if err := tx.Where("id = ? AND post_id = ?", optionID, postID).First(&option).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New("invalid option")
}
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("invalid option")
}
return err
}
@@ -86,9 +89,9 @@ func (r *VoteRepository) Unvote(postID, userID string) error {
var userVote model.UserVote
err := tx.Where("post_id = ? AND user_id = ?", postID, userID).First(&userVote).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil // 没有投票记录,直接返回
}
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil // 没有投票记录,直接返回
}
return err
}
@@ -113,7 +116,7 @@ func (r *VoteRepository) GetUserVote(postID, userID string) (*model.UserVote, er
var userVote model.UserVote
err := r.db.Where("post_id = ? AND user_id = ?", postID, userID).First(&userVote).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err