在 Laravel 5 中使用 UUID 作为主键

Cod*_*oet 5 php mysql laravel eloquent laravel-5

我正在尝试创建具有主键的表,该主键是定义为binary(16)而不是默认自动递增id字段的 UUID 。

我已经设法使用原始 SQL 语句创建迁移,但DB::statement如下所示:

DB::statement("CREATE TABLE `binary_primary_keys` (
                      `uuid` binary(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
                      `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
                      `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
                      PRIMARY KEY (`uuid`)
                  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");
Run Code Online (Sandbox Code Playgroud)

但是,我无法使模型正常工作。我已按照此处提供的教程进行操作。我已经这样定义了我的模型:

class UuidModel extends Model
{
    public $incrementing = false;
    public $primaryKey = 'uuid';

    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        /**
         * Attach to the 'creating' Model Event to provide a UUID
         * for the `id` field (provided by $model->getKeyName())
         */
        static::creating(function ($model) {
            $model->{$model->getKeyName()} = (string)$model->generateNewId();
            echo($model->{$model->getKeyName()});
        });
    }

    /**
     * Get a new version 4 (random) UUID.
     */
    public function generateNewId()
    {
        return Uuid::generate();
    }
}
Run Code Online (Sandbox Code Playgroud)

whereUuid是 的别名Webpatser\Uuid

一个问题,我在我是无法获得UuidModelEloquent作为教程解释。事实上,我没有看到一个Eloquent类。我来自Model而不是。我猜本教程是用 Laravel 4 编写的。

我很感激在 Laravel 5 中以 UUID 作为主键实现表的帮助。

编辑 1: 所以,如果我这样定义我的类:

use Illuminate\Database\Eloquent
class UuidModel extends Eloquent { ... }
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

PHP Fatal error:  Class 'Illuminate\Database\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8
Run Code Online (Sandbox Code Playgroud)

如果删除该use Illuminate\Database\Eloquent行,则会出现以下错误:

PHP Fatal error:  Class 'App\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8
Run Code Online (Sandbox Code Playgroud)

编辑 2: 我发现在创建static::creating实例时永远不会调用该事件UuidModel

我尝试在其中设置creating事件侦听器,AppServiceProvider但也没有调用它。有趣的creating是,常规 Laravel 生成的模型User也不会调用该事件。

class AppServiceProvider extends ServiceProvider
{
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    /**
     * Attach to the 'creating' Model Event to provide a UUID
     * for the `id` field (provided by $model->getKeyName())
     */
    echo "Booting...\n";
    UuidModel::creating(function ($model) {
        echo "Creating Uuid Model...\n";
        $model->{$model->getKeyName()} = (string)$model->generateNewId();
    });

    User::creating(function($user){
        echo "Creating User Model...";
        $user->name = 'Forced Name in boot()';
    });
}
public function register(){}

}
Run Code Online (Sandbox Code Playgroud)

Cod*_*oet 3

所以,我让这个东西像魅力一样工作(未经测试的单元测试):

  1. class UuidModel extends Eloquent是一个较旧的(Laravel 4)构造。class UuidModel extends Model我们在 Laravel 5 中使用
  2. 解决方案是移动

    UuidModel::creating(function ($model) {
        echo "Creating Uuid Model...\n";
        $model->{$model->getKeyName()} = (string)$model->generateNewId();
    });
    
    Run Code Online (Sandbox Code Playgroud)

    AppServiceProvider::boot()EventServiceProvider::boot()。不需要进行其他更改。一切都按预期进行。

我仍然不知道为什么 (2) 可以工作EventServiceProvider,但不能AppServiceProvider按照官方文档中的解释工作。但从名字来看,这或许就是它的意思。

  • @MartinBean我看到了,但那是映射到没有指定长度的BLOB类型。不完全确定 BLOB 是否与 BINARY(16) 一样高效,BINARY(16) 的数量本质上是 INT 大 4 倍。我相信 MySQL 不会在同一个表中存储 BLOB 值。 (3认同)