簡體   English   中英

在Laravel 5中使用UUID作為主鍵

[英]Using a UUID as primary key with Laravel 5

我正在嘗試創建具有主鍵的表,該主鍵是定義為binary(16)的UUID,而不是默認的自動遞增id字段。

我設法使用原始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;");

但是,我無法讓模型正常工作。 我按照這里提供的教程進行了操作 我已經定義了我的模型:

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();
    }
}

其中UuidWebpatser\\Uuid的別名。

一個問題,我有是我不能獲得UuidModelEloquent作為教程解釋。 事實上,我沒有看到一個Eloquent課程。 我是從Model衍生出來的。 我猜這個教程是用Laravel 4編寫的。

我很感激幫助實現將UUID作為Laravel 5主鍵的表。

編輯1:所以,如果我這樣定義我的類:

use Illuminate\Database\Eloquent
class UuidModel extends Eloquent { ... }

我收到以下錯誤:

PHP Fatal error:  Class 'Illuminate\Database\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8

如果我刪除use Illuminate\\Database\\Eloquent行,我會收到以下錯誤:

PHP Fatal error:  Class 'App\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8

編輯2:我發現在static::creating UuidModel實例時永遠不會調用static::creating事件。

我嘗試在AppServiceProvider設置creating事件監聽器,但是也沒有調用它。 有趣的是, 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(){}

}

所以,我得到的東西就像一個魅力(沒有經過測試的單元測試):

  1. class UuidModel extends Eloquent是一個較舊的(Laravel 4)構造。 我們在Laravel 5中使用class UuidModel extends Model
  2. 解決方案是移動

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

    AppServiceProvider::boot()EventServiceProvider::boot() 無需其他更改。 一切都按預期工作。

我仍然不知道為什么(2)在EventServiceProvider工作,而不是在官方文檔中解釋的AppServiceProvider中。 但從名稱來看,這可能是它的意圖。

將36chr UUID存儲為二進制(16)的想法怎么樣:

IMO 在沒有Laravel生成UUID方面有一個優勢 也就是說,如果新記錄(將來的某一天)從應用程序外部插入到數據庫中,則可以正確填充UUID字段。

我的建議:使用遷移創建UUID默認值觸發器

(此觸發器使DataBase服務器完成每次插入新客戶時生成UUID的工作)

<?php namespace MegaBank\HighInterestLoans\Updates;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;

class MigrationTriggerForCustomers extends Migration
{
public function up()
    {

        DB::unprepared('CREATE TRIGGER before_insert_customers
                      BEFORE INSERT ON    
                    `megabank_highinterestloans_customers` 
                      FOR EACH ROW
                      SET new.uuid = UNHEX(REPLACE(UUID(), "-","");');
    }

    public function down()
    {
        DB::unprepared('DROP TRIGGER `before_insert_customers`');
    }
}

最后,如果您想獲得UUID的人類可讀版本,請執行以下操作:

SELECT HEX(UUID) FROM customers;

無論如何,希望這有助於某人:-)

這是一種不使用事件的快速解決方案。

UUidModel.php

<?php        namespace App;

    use \Illuminate\Database\Eloquent\Model;

    use \Illuminate\Database\Eloquent\Builder;

    class UuidModel extends Model

    {

    /**

    * Insert the given attributes and set the ID on the model.

    *

    * @param  \Illuminate\Database\Eloquent\Builder  $query

    * @param  array  $attributes

    * @return void

    */

        protected function insertAndSetId(Builder $query, $attributes)

        {
            $keyName = $this->getKeyName();
            $id = $attributes[$keyName] = $this->generateNewId();
            $query->insert($attributes);
            $this->setAttribute($keyName, $id);
        }

    /**
    * Get a new version 4 (random) UUID.
    */
        public function generateNewId()
        {
            return 'uuid!!' ;// just for test
        }
    }
?>

模型示例Car.php

<?php namespace App;

    class Car extends UuidModel {
    }

也嘗試使用此包將自動生成並在您的模型中分配UUID字段,也可以通過UUIDs鍵顯示和更新。

https://github.com/EmadAdly/laravel-uuid

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM