在 Laravel 5 中使用 UUID 作为主键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31817067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using a UUID as primary key with Laravel 5
提问by Code Poet
I'm trying to create tables that will have a primary key which is a UUID defined as binary(16)
instead of the default auto-incrementing id
field.
我正在尝试创建具有主键的表,该主键是定义为binary(16)
而不是默认自动递增id
字段的 UUID 。
I've managed to create migrations using raw SQL statements though DB::statement
like so:
我已经设法使用原始 SQL 语句创建迁移,但DB::statement
如下所示:
DB::statement("CREATE TABLE `binary_primary_keys` (
`uuid` binary(16) NOT NULL DEFAULT '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();
}
}
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
PHP Fatal error: Class 'App\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8
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(){}
}
UuidModel::creating(function ($model) {
echo "Creating Uuid Model...\n";
$model->{$model->getKeyName()} = (string)$model->generateNewId();
});
UuidModel::creating(function ($model) {
echo "Creating Uuid Model...\n";
$model->{$model->getKeyName()} = (string)$model->generateNewId();
});
<?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`');
}
}
SELECT HEX(UUID) FROM customers;
<?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
}
}
?>
<?php namespace App;
class Car extends UuidModel {
}
##代码####代码####代码####代码####代码##',
`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;");
However, I have trouble getting the model working. I've followed the tutorial available here. I've defined my model like so:
但是,我无法使模型正常工作。我已经按照此处提供的教程进行操作。我已经这样定义了我的模型:
##代码##where Uuid
is an alias to Webpatser\Uuid
.
whereUuid
是 的别名Webpatser\Uuid
。
One problem, I'm having is I cannot derive UuidModel
from Eloquent
as explained in the tutorial. In fact I don't see an Eloquent
class. I'm deriving from Model
instead. I am guessing the tutorial was written in Laravel 4.
一个问题,我在我是无法获得UuidModel
从Eloquent
作为教程解释。事实上,我没有看到一个Eloquent
类。我Model
取而代之。我猜本教程是用 Laravel 4 编写的。
I would appreciate help in implementing tables with UUIDs as primary keys in Laravel 5.
我很感激在 Laravel 5 中以 UUID 作为主键实现表的帮助。
EDIT 1:So, if I define my class like so:
编辑 1:所以,如果我这样定义我的类:
##代码##I get the following error:
我收到以下错误:
##代码##If I remove the use Illuminate\Database\Eloquent
line, I get the following error:
如果删除该use Illuminate\Database\Eloquent
行,则会出现以下错误:
Edit 2:I have discovered that the static::creating
event is never called for when instances of UuidModel
are created.
编辑 2:我发现在创建static::creating
实例时永远不会调用该事件UuidModel
。
I tried setting up the creating
event listener in AppServiceProvider
but that's not being called as well. Interestingly, the creating
event is not called for a regular Laravel generated model User
either.
我尝试在其中设置creating
事件侦听器,AppServiceProvider
但也没有调用它。有趣的creating
是,常规 Laravel 生成的模型User
也不会调用该事件。
采纳答案by Code Poet
So, I got the thing working like a charm (not tested unit testing):
所以,我让事情像魅力一样工作(未经测试的单元测试):
class UuidModel extends Eloquent
is an older (Laravel 4) construct. We useclass UuidModel extends Model
in Laravel 5The solution was to move the
##代码##from
AppServiceProvider::boot()
toEventServiceProvider::boot()
. No other changes were required. Everything worked as expected.
class UuidModel extends Eloquent
是一个较旧的(Laravel 4)结构。我们class UuidModel extends Model
在 Laravel 5 中使用解决方案是移动
##代码##从
AppServiceProvider::boot()
到EventServiceProvider::boot()
. 不需要其他更改。一切都按预期进行。
I still don't know why (2) works in EventServiceProvider
and not in AppServiceProvider
as explained in the official docs. But judging from the name, that's perhaps the way it was meant to be.
我仍然不知道为什么 (2) 起作用EventServiceProvider
而不是AppServiceProvider
像官方文档中解释的那样起作用。但从名字来看,这也许就是它的本意。
回答by David Lundquist
How about this idea for storing a 36chr UUID as Binary(16) :
将 36chr UUID 存储为 Binary(16) 的想法如何:
IMO there is an advantage in not having Laravel generating the UUID. Namely, if new records (some day in the future) get inserted into the database from outside the application the UUID field is properly populated.
IMO没有让 Laravel 生成 UUID有一个优势。也就是说,如果新记录(未来某天)从应用程序外部插入数据库,则 UUID 字段会正确填充。
My suggestion: Create a UUID default value trigger using migrations
我的建议:使用迁移创建一个 UUID 默认值触发器
(this trigger makes the DataBase server do the work to generate the UUID each time a new customer is inserted)
(此触发器使数据库服务器在每次插入新客户时执行生成 UUID 的工作)
##代码##Finally, if you want to get a human-readable version of your UUID just do the following:
最后,如果您想获得人类可读的 UUID 版本,只需执行以下操作:
##代码##Anyway, hope this helps someone :-)
无论如何,希望这对某人有所帮助:-)
回答by Leonardo Jorge
This is a quick solution without using events.
这是一个不使用事件的快速解决方案。
UUidModel.php
用户界面模型.php
##代码##Model Example Car.php
模型示例 Car.php
##代码##回答by Emad Adly
also try use this package will automatically generate and assign UUID field in your model, also can show and update by UUIDs key.
也可以尝试使用这个包会自动在你的模型中生成和分配 UUID 字段,也可以通过 UUIDs 键显示和更新。