Magento 2 Database: Models, Resource Models & Collections

Mar 10, 2020

12686 Aleksander Kutseika

Magento 2 Database: Models, Resource Models & Collections

Find out what ORM is and discover the connection to a database as well as the functionality of each Magento 2 ORM component. Take your online store management to the next level with our insightful blog.

How does Connection to Database Works in Magento 2?
Magento 2 Resource Models
Magento 2 Models
Magento 2 Collections

How does Connection to Database Works in Magento 2?

In Magento 2, database connection settings are contained in the app/etc/env.php file:

The path to this file is stored in \Magento\Framework\Config\File\ConfigFilePool class in a private array $applicationConfigFiles.

There is a connection chain from the resource model to the database:

  • The method create() of \Magento\Framework\App\Bootstrap class is called in the index.php file. It calls the self public static method createObjectManagerFactory().
  • The method createObjectManagerFactory() calls self method createConfigFilePool() which creates a ConfigFilePool object and returns ObjectManagerFactory object where ConfigFilePool was set as a parameter.
    (ObjectManagerFactory is an object with complex operations. A global configuration creating is one of such operations.)
  • All custom resource models should be inherited from \Magento\Framework\Model\ResourceModel\Db\AbstractDb class. It has method getConnection() where \Magento\Framework\App\ResourceConnection object is called.

The \Magento\Framework\App\ResourceConnection contains fields and methods for operating with data from global configuration. It concerns the data from app/etc/env.php file. For example, ResourceConnection::DEFAULT_CONNECTION is default value and corresponds to [‘db’ => [‘connection’ => [‘default’ => […]]]]:


(You can create a new custom connection and set it to $connectionName in your custom resource model.)

Magento 2 Resource Models

As it’s been mentioned above, connection to the database is implemented through the resource model. Resource Models are data mappers for the storage structure. They are used for making transactions to the database.

A resource model extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb (With Magento 2, you no longer have to declare the model, resource model, adapters, and more in the configuration. So the process is much simpler than it used to be in Magento 1).

You need to define the table name and the primary key field name for the resource model because it’s necessary to know where to save the model state. They are specified by calling the _init() method in the protected _construct() method. Note that you call _init() from a single-underscore construct method, not the real double underscore PHP constructor. This single-underscore _construct() method is also the legacy from Magento 1 and is called by the real __construct() method inherited from \Magento\Framework\Model\ResourceModel class.


All interacting processes with database are stored in methods of resource models. They access to database tables using \Magento\Framework\DB\Adapter\Pdo\Mysql methods. It extends Zend_Db_Adapter_Pdo_Mysql class and implements Magento\Framework\DB\Adapter\AdapterInterface. Here is a mechanism of connection these classes to resource models:

  • The \Magento\Framework\DB\Adapter\Pdo\Mysql object is created in the Magento\Framework\Model\ResourceModel\Type\Db\Pdo\Mysql class in the protected method getDbConnectionClassName():

    It’s called in the protected method getDbConnectionInstance() which is called in public method getConnection().
  • The global configuration file app/etc/di.xml contains a preference:

    So, \Magento\Framework\Model\ResourceModel\Type\Db\Pdo\Mysql is a realization of ConnectionAdapterInterface.
  • The ConnectionAdapterInterface is called in \Magento\Framework\Model\ResourceModel\Type\Db\ConnectionFactory in the create() method:
  • The \Magento\Framework\Model\ResourceModel\Type\Db\ConnectionFactory is a realization of the \Magento\Framework\Model\ResourceModel\Type\Db\ConnectionFactoryInterface class. It is called in the \Magento\Framework\App\ResourceConnection (which is called in resource model as it was mentioned above and using in methods for connecting to database) in the __construct() method:

All transactions, operations with foreign keys, indexes, columns, tables are implemented in \Magento\Framework\DB\Adapter\Pdo\Mysql.

Magento Audit

Magento Audit

Take your online store to the next level with BelVG Magento Audit

Visit the page

Magento 2 Models

Models are data and behavior, representing entities. Anything represented by a database table is most likely going to be a model.

To create the model, you just create a class and extend it from \Magento\Framework\Model\AbstractModel. Again, note the single-underscore construct method. Do not confuse it with the real PHP constructor. Call the method _init() where resource model should be set.


This is required to support the inherited AbstractModel methods getResource() and getCollection().

Method getCollection() is deprecated. It won’t be used in future Magento 2 versions. It’s required to use collection factory instead for avoiding conflicts with your code.

The model has no direct access to the database, only the resource models.

Models contain methods only for managing objects with data which is supposed to be prepared for saving to a database or loading to a frontend. Even method load was “moved” to a resource model and will be deprecated from a model in future versions of Magento 2. It also contains different useful flags which are used for validating data before setting to database or preventing from unecessary transactions to database if a data in an object wasn’t changed. It’s used in method save() in the \Magento\Eav\Model\Entity class depending on different Magento 2 entities:

Vlad Yunusov

Partner With Us

Let's discuss how to grow your business. Get a Free Quote.
Talk to Vlad


Except load() method Magento2 model also contains the deprecated CRUD (“CRUD” stands for “Create, Read, Update, Delete.”) methods save() and delete(). The actions have been delegated to the resource model. Developers striving to write upgrade safe code should not use the CRUD methods on the model, as they will be removed at some point in the future. Instead, the models should be passed directly to the CRUD methods on the resource model.


Actually the method does both: If the $isDeleted parameter is specified, it sets the _isDeleted flag value; otherwise, it returns the current flag value. The method validateBeforeSave() uses a validator, which contains all the rules to validate the current model. It is called by the resource model save() method.

In the resource model save() method, the _dataSaveAllowed flag can stop saving after the beforeSave() method was called. This can be helpful in case some data validation failed. The resource models method save() checks saved object and runs updateObject() and saveNewObject(), which of them use \Magento\Framework\DB\Adapter\AdapterInterface object for working with databases. Mechanism of the method load() is similar:


Since the model load method will be removed at some point in the future, it is better to use plugins into the resource model load method instead of relying on these events.

The _afterLoad() method is used for processing an object directly after loading the data. Every time a Magento model is loaded, you can intercept it by observing the events model_load_before and model_load_after, which carries a simple data transfer object. The model instance itself is the key “object”.

magento development services

Magento Development Services

Take your online store to the next level with BelVG Magento development

Click to visit the page

Magento 2 Collections

Collections are encapsulating sets of models and related functionality, such as filtering, sorting, and paging.

A collection in Magento is a class that implements both the IteratorAggregate and the Countable PHP5 SPL interfaces. Collections are widely used in Magento to store a set of objects of a specific type.

Database in Magento2. Part 1. Models resource models and collections.1databases-in-magento2-configuration

 

The collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection.
When creating a resource collection, you need to specify which model it corresponds to, so that it can instantiate the appropriate classes after loading a list of records. It’s also necessary to know the matching resource model to be able to access the database. That’s why the class names of the model and the resource model are specified by using the _init() method in the protected _construct() method.

Database in Magento2. Part 1. Models resource models and collections.2magento-databases-how-to-configure

 

There isn’t the best choice to use method getCollection() of \Magento\Framework\Model\AbstractModel for getting entities collections as it will be remove in Magento 2 future versions. You should use collection factory. Here is an example of getting product collection in \Magento\Setup\Fixtures\Quote\QuoteGenerator:


The API you program against for collections is implemented by \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection.

The programmatic API for collections is implemented by \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection.


Collections provide several useful functions for defining and working with a result set. As you can see, the set of methods exposed by collections has not changed much from Magento 1.

Database in Magento2. Part 1. Models resource models and collections.3 e1499337132442models, resource models and collections in magento 2

 

A resource collection is necessary to create a set of model instances and operate on them. Resource collections lazy load the recordset they represent. The first time the item list is accessed, a collection will load automatically. After that, a collection will not load again, even if the load() method is explicitly called.

Collections are very close to the database layer. Their task is to retrieve a set of rows from the database, then iterate over them, and for each row, instantiate the matching model class.

It solves these main issues:

  • Provides a container for storing collections of objects.
  • Prevents unnecessary data loading.
  • Stores all objects during a session.
  • Provides an interface for filtering and sorting entities of a specific kind.

The Magento ORM is used by the Repository implementations that are part of the Magento 2 service contracts. This is an important variation from Magento 1, as a module should no longer rely on other modules using a specific ORM, and instead of it use only the entity repositories. The service contracts will be covered in more details in the second part of the article.

Please check the second part of the article: Database in Magento 2: Service Contracts

Looking for an expert Magento development team to realize your projects? We can help!

The following people contributed to the article: Sasha Mitskevich.

Vlad Yunusov

Partner With Us

Looking for a partner to grow your business? We are the right company to bring your webstore to success. Talk to Vlad

5 Comments

  1. Hi, Dzmitry!
    There seems to be a simple misspelling – it should be “delete data in a database”. Thanks for raising awareness! We will immediately edit the article.

Post a new comment

BelVG Newsletter
Subscribe to our mailing list and get interesting stuff and updates to your email inbox.
Email *