Magento2创建SQL安装脚本[开发教程]

在本文中,我们将了解如何在Magento 2中安装和升级模块的sql脚本。当您安装或升级一个模块时,您可能需要更改数据库结构或为当前表添加一些新数据。为了做到这一点,Magento 2为你提供了一些你可以使用的类.


##Magento2安装升级SQL脚本概述

  • InstallSchema - 当安装模块设置数据库结构时,该类将运行
  • InstallData - 当模块安装到数据库表的初始数据时,该类将运行。
  • UpgradeSchema - 当模块升级为设置数据库结构时,该类将运行
  • UpgradeData - 当模块升级到从表中添加/删除数据时,该类将运行。
  • Recurring - 循环
  • Uninstall - 卸载

所有的类将位于 app/code/Vendor/Module/Setup 文件夹。当您运行以下命令行时,模块 安装/升级 脚本将运行:

php bin/magento setup:upgrade

在本文中,我们将使用示例模块Magentochina_HelloWorld创建一些演示表和数据。
##安装模式/安装数据 InstallSchema / InstallData
安装模式(InstallSchema)和安装数据(InstallData)类将在模块安装期间运行。
magento 2中的InstallSchema安装脚本将用于更改数据库模式(创建或更改数据库表)。这是创建magentochina_post表的设置脚本:
文件:

app/code/Magentochina/HelloWorld/Setup/InstallSchema.php

<?php
namespace Magentochina\HelloWorld\Setup;

class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{
    /**
     * install tables
     *
     * @param \Magento\Framework\Setup\SchemaSetupInterface $setup
     * @param \Magento\Framework\Setup\ModuleContextInterface $context
     * @return void
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
        if (!$installer->tableExists('magentochina_helloworld_post')) {
            $table = $installer->getConnection()->newTable(
                $installer->getTable('magentochina_helloworld_post')
            )
            ->addColumn(
                'post_id',
                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                null,
                [
                    'identity' => true,
                    'nullable' => false,
                    'primary'  => true,
                    'unsigned' => true,
                ],
                'Post ID'
            )
            ->addColumn(
                'name',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                255,
                ['nullable => false'],
                'Post Name'
            )
            ->addColumn(
                'url_key',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                255,
                [],
                'Post URL Key'
            )
            ->addColumn(
                'post_content',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                '64k',
                [],
                'Post Post Content'
            )
            ->addColumn(
                'tags',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                255,
                [],
                'Post Tags'
            )
            ->addColumn(
                'status',
                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                1,
                [],
                'Post Status'
            )
            ->addColumn(
                'featured_image',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                255,
                [],
                'Post Featured Image'
            )
            ->addColumn(
                'sample_country_selection',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                3,
                [],
                'Post Sample Country Selection'
            )
            ->addColumn(
                'sample_upload_file',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                255,
                [],
                'Post Sample File'
            )
            ->addColumn(
                'sample_multiselect',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                '64k',
                [],
                'Post Sample Multiselect'
            )

            ->addColumn(
                'created_at',
                \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
                null,
                [],
                'Post Created At'
            )
            ->addColumn(
                'updated_at',
                \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
                null,
                [],
                'Post Updated At'
            )
            ->setComment('Post Table');
            $installer->getConnection()->createTable($table);

            $installer->getConnection()->addIndex(
                $installer->getTable('magentochina_helloworld_post'),
                $setup->getIdxName(
                    $installer->getTable('magentochina_helloworld_post'),
                    ['name','url_key','post_content','tags','featured_image','sample_upload_file'],
                    \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
                ),
                ['name','url_key','post_content','tags','featured_image','sample_upload_file'],
                \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
            );
        }
        $installer->endSetup();
    }
}

这个文件,我们会看到:
类必须继承于 \Magento\Framework\Setup\InstallSchemaInterface
该类必须具有两个参数 SchemaSetupInterfaceModuleContextInterface的 **install()**方法。
SchemaSetupInterface是提供许多与数据库服务器交互的函数的安装对象。ModuleContextInterface只有一个方法 getVersion(),它将返回模块的当前版本。
在上面的例子中,我们创建了一个名为magentochina_post的表和post_id、name、post_content、created_at…等字段
InstallData将在InstallSchema类之后运行,以向数据库表中添加数据。
文件:

app/code/Magentochina/HelloWorld/Setup/InstallData.php

<?php
namespace Magentochina\HelloWorld\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{
    protected $_postFactory;

    public function __construct(\Magentochina\HelloWorld\Model\BlogFactory $postFactory)
    {
        $this->_postFactory = $postFactory;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $data = [
            'name' => "Sample title 1",
            'post_content' => "Sample content by www.MagentoChina.org"
        ];
        $post = $this->_postFactory->create();
        $post->addData($data)->save();
    }
}

这个类将具有与 InstallSchema相同的概念。
##升级模式/升级数据 UpgradeSchema/UpgradeData
当模块安装或升级时,这两个文件都将运行。这个类与安装类是不同的,因为它们将在 每次模块升级时运行。因此,我们需要检查版本,并将脚本按每个版本号分离
###升级模式
文件:

app/code/Magentochina/HelloWorld/Setup/UpgradeSchema.php

<?php
namespace Magentochina\HelloWorld\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{
	public function upgrade( SchemaSetupInterface $setup, ModuleContextInterface $context ) {
		$installer = $setup;

		$installer->startSetup();
		if(version_compare($context->getVersion(), '1.0.1', '<')) {
			$installer->getConnection()->dropColumn(
				$installer->getTable( 'mageplaza_post' ),
				'created_at'
			);
		}

		$installer->endSetup();
	}
}

在这个类中,我们使用 **upgrade()**方法,它将在每次升级模块时运行。我们还需要比较版本以添加每个版本的脚本。
###升级数据:
这与 UpgradeSchema类相同
文件:

app/code/Magentochina/HelloWorld/Setup/UpgradeData.php

<?php
namespace Magentochina\HelloWorld\Setup;

use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;

class UpgradeData implements UpgradeDataInterface
{
	protected $_postFactory;

	public function __construct(\Magentochina\HelloWorld\Model\BlogFactory $postFactory)
	{
		$this->_postFactory = $postFactory;
	}

	public function upgrade( ModuleDataSetupInterface $setup, ModuleContextInterface $context ) {
		if ( version_compare($context->getVersion(), '1.0.1', '<' )) {
			$data = [
				'name' => "Sample title 2",
				'post_content' => "Sample content 2"
			];
			$post = $this->_postFactory->create();
			$post->addData($data)->save();
		}
	}
}

###循环 Recurring

循环 Recurring脚本它将在每次命令行(php bin/magento setup:upgrade)执行模块设置脚本后运行.
这个脚本将被定义为InstallSchema类,但与类的名称不同。这个类的实例中可以看出 vendor/magento/module-indexer/Setup/Recurring.php

###卸载 Uninstall
Magento 2为我们提供了卸载模块的方法,它将删除所有的表和数据。这是这个类的例子:
文件:

app/code/Magentochina/Example/Setup/Uninstall.php

<?php
namespace Magentochina\Example\Setup;

use Magento\Framework\Setup\UninstallInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;

class Uninstall implements UninstallInterface
{
	public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
	{
		$installer = $setup;
		$installer->startSetup();

		$installer->getConnection()->dropTable($installer->getTable('magentochina_post')); //删除表

		$installer->endSetup();
	}
}

本文翻译自mageplaza的Magento2模块开发教程,而且正在翻译中.

翻译也是非常好的学习方式,如果您遇到需要了解我们还未翻译的Magento2模块开发教程,而你又想分享的内容,请发表文章之后,在下面附上地址。
###如果觉得本站翻译得内容对您有帮助,又没有时间帮助翻译回馈社区.请打赏我们,您的支持是我们的动力:

####转载说明:非常欢迎转载,但是必须保证文章的完整性并附上原文地址和翻译原文的地址,保证阅读者不会产生歧义.