You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检查待插入的学生姓名是否已存在于数据库?(基于GORM)

解决学生姓名重复问题的两种方案

方案一:插入前主动查询校验

先查询数据库中是否存在同名学生,确认无重复后再执行插入。同时修正原代码中接收器(receiver)的错误(原代码误用student作为接收器,实际应该是*studentRepository,因为要访问结构体中的db实例):

import "fmt"

type studentRepository struct {
    db *gorm.DB
}

type Student struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func(p *studentRepository) CreateStudent(v Student) (*Student, error) {
    // 查询是否存在同名学生
    var existing Student
    err := p.db.Where("name = ?", v.Name).First(&existing).Error
    switch err {
    case nil:
        // 查询到结果,姓名重复
        return nil, fmt.Errorf("姓名%s已存在", v.Name)
    case gorm.ErrRecordNotFound:
        // 无重复,执行插入
        if insertErr := p.db.Create(&v).Error; insertErr != nil {
            return nil, insertErr
        }
        return &v, nil
    default:
        // 其他查询异常
        return nil, err
    }
}

方案二:数据库层面添加唯一约束

通过给Student结构体的Name字段添加唯一约束,让数据库直接拦截重复数据,再捕获插入时的约束冲突错误:

首先修改结构体,添加GORM唯一约束标签:

type Student struct {
    Name string `json:"name" gorm:"unique;not null"`
    Age  int    `json:"age"`
}

然后修改插入方法,捕获约束冲突错误(以MySQL为例,唯一冲突错误码为1062):

import (
    "fmt"
    "github.com/go-sql-driver/mysql"
)

func(p *studentRepository) CreateStudent(v Student) (*Student, error) {
    if err := p.db.Create(&v).Error; err != nil {
        // 判断是否为MySQL唯一约束冲突错误
        if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1062 {
            return nil, fmt.Errorf("姓名%s已存在", v.Name)
        }
        return nil, err
    }
    return &v, nil
}

方案对比

  • 方案一:逻辑直观,但存在竞态窗口——若多个请求同时插入同名数据,可能在检查完成后、插入前,另一个请求已完成插入,导致重复。
  • 方案二:数据库层面强制保证唯一性,彻底避免重复问题,是更可靠的方案,但需要适配不同数据库的错误码。

内容的提问来源于stack exchange,提问作者adrian sitorus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:48:53