自定義type
根據官方文檔,建立TinyIntType類,內建Type,并重寫
getName
,
getSqlDeclaration
,
convertToPHPValue
,
getBindingType
等方法。
TinyIntType.php完整代碼:
<?php
namespace db\types;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
/**
* 擴充DBAL元件類型
*
* 遷移元件依賴的DBAL元件預設并不支援tinyint類型
* 此類是為mysql支援tinyint類型而擴充的類
*
* @author tangbo<[email protected]>
*/
class TinyIntType extends Type
{
public function getName()
{
return 'tinyint';
}
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
$sql = 'TINYINT';
if (is_numeric($fieldDeclaration['length']) && $fieldDeclaration['length'] > ) {
$sql .= '(' . ((int) $fieldDeclaration['length']) . ')';
} else {
$sql .= '(3)';
}
if (!empty($fieldDeclaration['unsigned'])) {
$sql .= ' UNSIGNED';
}
if (!empty($fieldDeclaration['autoincrement'])) {
$sql .= ' AUTO_INCREMENT';
}
return $sql;
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return (null === $value) ? null : (int) $value;
}
public function getBindingType()
{
return ParameterType::INTEGER;
}
}
其中
getSqlDeclaration
方法是用于生成sql語句,需要根據傳入的參數處理sql拼接。
注冊自定義類型
Type::addType(TinyIntType::TYPENAME, 'db\types\TinyIntType');
$connection->getDatabasePlatform()->registerDoctrineTypeMapping(TinyIntType::TYPENAME, TinyIntType::TYPENAME);
這樣,你在編寫遷移類代碼的時候就可以使用tinyint了,例如:
public function up(Schema $schema): void
{
$table = $schema->createTable('test1');
$table->addColumn('id', 'integer')->setUnsigned(true)->setAutoincrement(true);
$table->addColumn('status', 'tinyint')->setLength()->setDefault();
$table->setPrimaryKey(['id']);
}
解決enum類型沖突
遷移元件不支援enum類型,也無法自定義該類型。如果內建遷移元件的時候資料庫裡已經存在表且有enum類型的字段,那麼執行遷移指令時就會報錯。
為了解決這個問題,我們需要把enum映射為string類型即可:
$connection->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
結語
至此,我們已經完成了遷移元件的所有遷移工作,并且已經能很好的在項目中使用它。
目前內建的是版本管理的方式,是遷移元件預設支援的,也是laravel架構內建的遷移方式。還有之前說到的另一種diff方式的遷移,diff方式能夠更精準的控制表結構。
下一章我們來詳細研究如和內建diff方式的資料遷移元件。
在我的代碼庫可以檢視這篇文章的詳細代碼,歡迎star。