Magento 2具有特殊的机制,允许你创建数据库表,修改现有的,甚至添加一些数据到他们(如安装数据,已被添加在模块安装)。 这种机制允许这些变化可以在不同的设备之间传输。
关键的概念是,而不是做你能做的一次又一次重新安装系统时,手动SQL操作,开发人员创建一个安装(或升级)脚本包含数据。 每次安装模块时,脚本将被执行。
Magento 2有四种类型的脚本:installschema,installdata,upgradeschema和upgradedata。 安装脚本只执行一次,而升级脚本每次执行模块版本被更改时执行。
要查看所有四种脚本类型,我们将完成以下问候页任务:
- 创建
greeting_message
表和列greeting_id 和 message. - 添加两个记录: “Happy New Year”, “Happy Holidays”.
- 接下来,修改表添加另一个字段,“season”,我们添加了记录“Happy Thanksgiving”和“Fall”。
- 更新第一和第二记录的类型。
我们需要采取的步骤来完成这些任务:
- 创建新模块.
- 创建 InstallSchema 脚本.
- 创建 InstallData 脚本.
- 添加一个新模块并验证创建数据表。
- 创建 UpgradeSchema 脚本.
- 创建 UpgradeData 脚本.
- 运行升级脚本并验证表已更改。
让我们走过每一步。
1:创建新模块
创建新模块 Learning_GreetingMessage
.
进入app/code
文件夹和创建文件夹 Learning
个 Learning/GreetingMessage
:
$ cd <magento2_root>/app/code
$ mkdir Learning
$ mkdir Learning/GreetingMessage
现在创建两个文件:
Learning/GreetingMessage/registration.php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
MagentoFrameworkComponentComponentRegistrar::register(
MagentoFrameworkComponentComponentRegistrar::MODULE,
'Learning_GreetingMessage',
__DIR__
);
Learning/GreetingMessage/etc/module.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* * See COPYING.txt for license details.
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Learning_GreetingMessage" setup_version="0.0.1">
</module>
</config>
2: 创建 InstallSchema 脚本
创建一个InstallSchema脚本,在 app/code/Learning/GreetingMessage
文件夹 和创建一个Setup
文件夹。
$ cd <magento2_root>/app/code/Learning/GreetingMessage
$ mkdir Setup
创建 Setup/InstallSchema.php
文件
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace LearningGreetingMessageSetup;
use MagentoFrameworkSetupInstallSchemaInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupSchemaSetupInterface;
/**
* @codeCoverageIgnore
*/
class InstallSchema implements InstallSchemaInterface
{
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
/**
* Create table 'greeting_message'
*/
$table = $setup->getConnection()
->newTable($setup->getTable('greeting_message'))
->addColumn(
'greeting_id',
MagentoFrameworkDBDdlTable::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Greeting ID'
)
->addColumn(
'message',
MagentoFrameworkDBDdlTable::TYPE_TEXT,
255,
['nullable' => false, 'default' => ''],
'Message'
)->setComment("Greeting Message table");
$setup->getConnection()->createTable($table);
}
}
让我们花点时间看看代码。
installschema文件都是非常典型的。 主代码位于install()
方法,有一个 $setup
参数。 这是一个关键参数,因为它提供了访问 Connection()
允许数据库操作的。
连接是 MagentoFrameworkDBAdapterPdoMysql
一个实例类。
Magento使用DDL(数据定义语言)来操纵数据库。 你可以在Magento 2核心代码找到DDL的各种例子。
3:创建 InstallData 脚本
创建 Setup/InstallData.php
文件:
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace LearningGreetingMessageSetup;
use MagentoFrameworkSetupInstallDataInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupModuleDataSetupInterface;
/**
* @codeCoverageIgnore
*/
class InstallData implements InstallDataInterface
{
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
/**
* Install messages
*/
$data = [
['message' => 'Happy New Year'],
['message' => 'Marry Christams']
];
foreach ($data as $bind) {
$setup->getConnection()
->insertForce($setup->getTable('greeting_message'), $bind);
}
}
}
4: 添加新模块并验证创建数据表
现在是运行安装脚本并验证带有初始数据的表的时候了,所以我们将运行setup:upgrade
脚本。
$ cd <magento2_root>
$ php bin/magento setup:upgrade
你应该看到一长串包含的模块Learning_GreetingMessage
.
现在让我们连接数据库: mysql -u<user> -p<password> <database>
SHOW TABLES LIKE “%greeting%”
+------------------------------------+
| Tables_in_magento_210 (%greeting%) |
+------------------------------------+
| greeting_message |
+------------------------------------+
SELECT * FROM greeting_message;
+-------------+-----------------+
| greeting_id | message |
+-------------+-----------------+
| 1 | Happy New Year |
| 2 | Happy Holidays |
+-------------+-----------------+
检查表和数据是否存在
这是怎么工作的? 当你创建新模块运行 bin/magento setup:upgrade
脚本,Magento的检查代码,看有没有安装模块。 如果它找到任何,它检查是否有任何安装脚本,如果是的话,运行它们。 在那之后,Magento更新表格setup_module提出关于模块的版本信息有:
SELECT * FROM setup_module WHERE module='Learning_GreetingMessage';
+--------------------------+----------------+--------------+
| module | schema_version | data_version |
+--------------------------+----------------+--------------+
| Learning_GreetingMessage | 0.0.1 | 0.0.1 |
+--------------------------+----------------+--------------+
5: 创建 UpgradeSchema 脚本
要查看升级脚本如何工作,我们将向数据库添加一些数据。
首先,改变版本在 etc/module.xml
文件为0.0.2:
<module name="Learning_GreetingMessage" setup_version="0.0.2">
创建文件 Setup/UpgradeSchema.php
:
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace LearningGreetingMessageSetup;
use MagentoFrameworkSetupUpgradeSchemaInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupSchemaSetupInterface;
/**
* Upgrade the Catalog module DB scheme
*/
class UpgradeSchema implements UpgradeSchemaInterface
{
/**
* {@inheritdoc}
*/
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '0.0.2', '<')) {
$setup->getConnection()->addColumn(
$setup->getTable('greeting_message'),
'season',
[
'type' => MagentoFrameworkDBDdlTable::TYPE_TEXT,
'length' => 16,
'nullable' => false,
'default' => '',
'comment' => 'Season'
]
);
}
$setup->endSetup();
}
}
注意“version_compare”线。 如前所述,该upgradescript将每一次的版本中执行module.xml
。 因此,我们只希望当前的版本升级脚本执行,而不是以前的升级。 这就是为什么我们把升级纳入“如果”条款。
6: 创建 UpgradeData 脚本
创建文件 Setup/UpgradeData.php
:
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace LearningGreetingMessageSetup;
use MagentoFrameworkSetupUpgradeDataInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupModuleDataSetupInterface;
/**
* Upgrade Data script
*/
class UpgradeData implements UpgradeDataInterface
{
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if ($context->getVersion()
&& version_compare($context->getVersion(), '0.0.2') < 0
) {
$table = $setup->getTable('greeting_message');
$setup->getConnection()
->insertForce($table, ['message' => 'Happy Thanksgiving, 'season' => 'fall']);
$setup->getConnection()
->update($table, ['season' => 'winter'], 'greeting_id IN (1,2)');
}
$setup->endSetup();
}
}
7: 运行升级脚本并验证表已更改
我们会再次运行setupupgrade脚本:
$ cd <magento2_root>
$ php bin/magento setup:upgrade
现在,我们可以连接到数据库,并验证我们的变化:
select * from greeting_message;
+-------------+--------------------+--------+
| greeting_id | message | season |
+-------------+--------------------+--------+
| 1 | Happy New Year | winter |
| 2 | Happy Holidays | winter |
| 3 | Happy Thanksgiving | fall |
+-------------+--------------------+--------+