在这篇博文中,我们将了解如何设置magento模型并执行与数据库相关的操作。

要在magento中设置模型,我们需要添加许多文件,最快的方法是使用代码生成工具,您可以在线找到许多用于magento2代码生成的工具,但我用于此博客的工具是这个

要安装此工具,请转到magento2根文件夹并运行此命令

curl -LO http://pestle.pulsestorm.net/pestle.phar
chmod + x pestle.phar

接下来运行此代码

./pestle.phar generate_crud_model Magease_Hello测试

这应该为模型生成所有必需的文件

Creating: /var/www/html/magento2/app/code/Magease/Hello/Model/TestInterface.php
Creating: /var/www/html/magento2/app/code/Magease/Hello/Model/ResourceModel/Test/Collection.php
Creating: /var/www/html/magento2/app/code/Magease/Hello/Model/ResourceModel/Test.php
Creating: /var/www/html/magento2/app/code/Magease/Hello/Model/Test.php
Creating: /var/www/html/magento2/app/code/Magease/Hello/Setup/InstallSchema.php
Creating: /var/www/html/magento2/app/code/Magease/Hello/Setup/InstallData.php

让我们详细查看文件

 

Setup Script

Magease/Hello/Setup/InstallSchema.php文件包含创建数据库表的代码,这在模块安装期间仅执行一次,该文件的内容是

<?php
namespace Magease\Hello\Setup;
class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{
public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
//START: install stuff
//END: install stuff

//START table setup
$table = $installer->getConnection()->newTable(
$installer->getTable('magease_hello_test')
)->addColumn(
'magease_hello_test_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
null,
[ 'identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true, ],
'Entity ID'
)->addColumn(
'title',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
[ 'nullable' => false, ],
'Demo Title'
)->addColumn(
'creation_time',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
[ 'nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT, ],
'Creation Time'
)->addColumn(
'update_time',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
[ 'nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE, ],
'Modification Time'
)->addColumn(
'is_active',
\Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
null,
[ 'nullable' => false, 'default' => '1', ],
'Is Active'
);
$installer->getConnection()->createTable($table);
//END table setup
$installer->endSetup();
}
}

查看文件内容,可以清楚地知道如何创建表,你也可以根据你的需要编辑这个表格。

文件Magease/Hello/Setup/InstallData.php用于为模块设置初始数据,稍后我们将详细讨论这一点。

在这一点上,如果你查看你的数据库表,你会发现在你的数据库中看不到“magease_hello_test”这张表,因为我们之前已经建立了模型,版本0.0.1已经在magento中启用。因此,magento不会运行安装脚本,因为magento已经安装了模块。

若要修复,请参阅magento2 数据库中的“setup_module”表,它应该有'Magease_Hello'这一条目,从表中删除该条目并运行该命令

bin/magento setup:upgrade

这将再次运行安装脚本并创建表

 

Model File

模型文件位于'‘Magease/Hello/Model/Test.php
文件中的代码是

<?php
namespace Magease\Hello\Model;
class Test extends \Magento\Framework\Model\AbstractModel implements TestInterface, \Magento\Framework\DataObject\IdentityInterface
{
const CACHE_TAG = 'magease_hello_test';

protected function _construct()
{
$this->_init('Magease\Hello\Model\ResourceModel\Test');
}

public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
}

CACHE_TAGmagento2模型中很重要,我们稍后将详细介绍它是什么,只要记住它应该是唯一的。

要在块中使用模型,我们需要注入它,在Magento2中我们一直需要依赖注入,绝不应该直接使用“new”或“Mage::getModel”创建块实例。

让我们看看如何在我们的模块中使用这个模型

在我们的Magease\Hello\Block\Main中,我们将添加这个代码

<?php
namespace Magease\Hello\Block;

class Main extends \Magento\Framework\View\Element\Template
{
protected $_testFactory;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magease\Hello\Model\TestFactory $testFactory
)
{
$this->_testFactory = $testFactory;
parent::__construct($context);
}
protected function _prepareLayout()
{
$test = $this->_testFactory->create();
$test->setTitle('Test Title');
$test->save();
$this->setTestModel($test);
}
}

您注意到类\Magease\Hello\Model\TestFactory不存在,我们还没有创造它。Factory是magento2中的特殊类,任何名为Factory的类,magento都会自动生成它并将其放在var/generation/vendor/module/model文件夹中

在我们的模板文件“content.phtml”中,我们将编写代码

<h1><?php echo __('Model Saved With Entity ID %1',$block->getTestModel()->getData('magease_hello_test_id')); ?></h1>

当您打开URL时,它将执行数据库条目并显示ID。

Magento2模型与magento1模型非常相似,因此load()delete()等函数都可以使用。

$test = $this->_testFactory->create();
$test->setTitle('Test Title');
$test->save();

$test->load(2);
print_r($test->getData());

$test->delete(2);

Collection

该集合位于'‘Magease\Hello\Model\ResourceModel\Test\Collection.php'代码中

<?php
namespace Magease\Hello\Model\ResourceModel\Test;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{
$this->_init('Magease\Hello\Model\Test','Magease\Hello\Model\ResourceModel\Test');
}
}

我们可以像magento1一样进行标准的collection操作

$test = $this->_testFactory->create();
$collection = $test->getCollection();
foreach($collection as $row){
print_r($row->getData());
}

Resource Model

资源模型是执行SQL查询的地方,模型文件包含整个数据库逻辑,但资源文件执行SQL操作。

例如在模型文件中,可以编写此代码

<?php
namespace Magease\Hello\Model;
class Test extends \Magento\Framework\Model\AbstractModel implements TestInterface, \Magento\Framework\DataObject\IdentityInterface
{
const CACHE_TAG = 'magease_hello_test';

protected function _construct()
{
$this->_init('Magease\Hello\Model\ResourceModel\Test');
}

public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
public function loadByTitle($title){
if(!$title){
$title = $this->getTitle();
//random data logic. can be much more complex.
//this is just example
}
$id = $this->getResource()->loadByTitle($title);
return $this->load($id);
}
}

在资源模型将有此代码

<?php
namespace Magease\Hello\Model\ResourceModel;
class Test extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
$this->_init('magease_hello_test','magease_hello_test_id');
}
public function loadByTitle($title){
$table = $this->getMainTable();
$where = $this->getConnection()->quoteInto("title = ?", $title);
$sql = $this->getConnection()->select()->from($table,array('magease_hello_test_id'))->where($where);
$id = $this->getConnection()->fetchOne($sql);
return $id;
}
}

在我们的块文件中,我们调用模型函数

<?php
namespace Magease\Hello\Block;

class Main extends \Magento\Framework\View\Element\Template
{
protected $_testFactory;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magease\Hello\Model\TestFactory $testFactory
)
{
$this->_testFactory = $testFactory;
parent::__construct($context);
}
protected function _prepareLayout()
{
$test = $this->_testFactory->create();
$test->loadByTitle('Test Title');
$this->setTestModel($test);
}
}

这是magento中的一种重要设计模式,模型应该具有数据库逻辑和资源模型的实际SQL操作。