如何在Laravel中创建带字符串前缀的自增主键并自动插入数据表?
实现带前缀的自增自定义主键(Laravel环境)
要实现类似std-1000格式的自动递增主键,且能像$table->id()一样自动插入,可采用以下两种方案:
方案一:模型事件生成(快速实现,低并发场景适用)
1. 创建迁移文件
不用默认的id()方法,手动定义字符串类型的主键:
Schema::create('students', function (Blueprint $table) { $table->string('id')->primary(); // 自定义字符串主键 $table->string('name'); // 示例字段,根据实际需求添加 $table->timestamps(); });
2. 模型中配置主键与生成逻辑
在对应模型(比如Student.php)中,关闭自增主键,并通过creating事件自动生成主键值:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Student extends Model { protected $primaryKey = 'id'; // 指定主键字段 public $incrementing = false; // 主键非自增整数,关闭自动递增 protected $keyType = 'string'; // 主键类型为字符串 protected $fillable = ['name']; // 可填充字段,根据实际调整 protected static function booted() { static::creating(function ($model) { // 获取当前表中最大的主键序号 $lastRecord = static::orderBy('id', 'desc')->first(); if ($lastRecord) { // 提取序号部分并递增 $lastNumber = (int)str_replace('std-', '', $lastRecord->id); $nextNumber = $lastNumber + 1; } else { // 初始序号从1000开始 $nextNumber = 1000; } // 拼接生成最终主键 $model->id = 'std-' . $nextNumber; }); } }
创建新记录时(比如Student::create(['name' => '张三'])),主键会自动生成并插入。
方案二:数据库触发器生成(高并发场景推荐)
此方案通过数据库触发器保证主键生成的唯一性,避免并发插入时的重复问题。
1. 创建迁移文件
新增一个自增整数字段作为内部序列,再定义业务主键:
Schema::create('students', function (Blueprint $table) { $table->bigIncrements('sequence_id'); // 内部自增序列,用于生成序号 $table->string('id')->unique(); // 业务主键,格式为std-xxxx $table->string('name'); // 示例字段 $table->timestamps(); }); // 创建数据库触发器,插入时自动生成业务主键 DB::unprepared(' CREATE TRIGGER generate_student_id BEFORE INSERT ON students FOR EACH ROW BEGIN -- sequence_id从1开始,加999得到初始序号1000 SET NEW.id = CONCAT("std-", NEW.sequence_id + 999); END ');
2. 模型配置
在模型中指定业务主键为id,关闭自动递增:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Student extends Model { protected $primaryKey = 'id'; public $incrementing = false; protected $keyType = 'string'; protected $fillable = ['name']; }
插入记录时,数据库会自动通过触发器生成std-1000、std-1001格式的主键,无需手动处理,且完全避免并发冲突。
内容的提问来源于stack exchange,提问作者Solutions
相关产品推荐
相关产品推荐

