{"id":13669,"date":"2020-03-10T13:50:13","date_gmt":"2020-03-10T11:50:13","guid":{"rendered":"https:\/\/belvg.com\/blog\/?p=13669"},"modified":"2026-05-12T11:25:30","modified_gmt":"2026-05-12T09:25:30","slug":"database-in-magento-2-models-resource-models-and-collections","status":"publish","type":"post","link":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html","title":{"rendered":"Magento 2: Models, Resource Models and Collections in 2026"},"content":{"rendered":"\n<p>Magento 2 uses an Object-Relational Mapping (ORM) system to manage how application data interacts with the database.<\/p>\n<p><!--more--><\/p>\n<p>This article explains how Magento 2 connects to the database and how the core ORM components, such as Models, Resource Models, and Collections, work together to handle CRUD operations, data retrieval, and entity management. You&rsquo;ll also see how these components fit into modern Magento architecture, where Service Contracts are now the preferred layer for business logic and API-safe development.<\/p>\n<p><a href=\"#step_1\">How does Connection to Database Work in Magento 2?<br>\n<\/a><a href=\"#step_2\">Magento 2 Resource Models<br>\n<\/a><a href=\"#step_3\">Magento 2 Models<br>\n<\/a><a href=\"#step_4\">Magento 2 Collections<br>\n<\/a><a href=\"#step_5\">Conclusion<\/a><\/p>\n<h2 id=\"step_1\">How does Connection to Database Work in Magento 2?<\/h2>\n<p>In Magento 2, database connection settings are contained in the <strong>app\/etc\/env.php<\/strong> file:<\/p>\n<p>The path to this file is stored in <strong>\\Magento\\Framework\\Config\\File\\ConfigFilePool<\/strong> class in a private array <strong><em>$applicationConfigFiles<\/em><\/strong>.<\/p>\n<p>There is a connection chain from the resource model to the database:<\/p>\n<ul>\n<li>The method <strong><em>create()<\/em><\/strong> of <strong>\\Magento\\Framework\\App\\Bootstrap<\/strong> class is called in the <strong>index.php<\/strong> file. It calls the self public static method <strong><em>createObjectManagerFactory()<\/em><\/strong>.\n<pre class=\"\">        public static function createObjectManagerFactory($rootDir, array $initParams)\r\n        {\r\n\r\n            $dirList = self::createFilesystemDirectoryList($rootDir, $initParams);\r\n            $driverPool = self::createFilesystemDriverPool($initParams);\r\n            $configFilePool = self::createConfigFilePool();\r\n            return new ObjectManagerFactory($dirList, $driverPool, $configFilePool);\r\n        }\r\n<\/pre>\n<\/li>\n<li>The method&nbsp;<em><strong>createObjectManagerFactory()<\/strong><\/em>&nbsp;calls the self method&nbsp;<em><strong>createConfigFilePool()<\/strong><\/em>, which creates a&nbsp;<em><strong>ConfigFilePool<\/strong><\/em>&nbsp;object and returns&nbsp;<em><strong>an ObjectManagerFactory<\/strong><\/em>&nbsp;object where the&nbsp;<em><strong>ConfigFilePool<\/strong><\/em>&nbsp;was set as a parameter.<br>\n(<strong><em>ObjectManagerFactory<\/em><\/strong> is an object with complex operations. A global configuration creation is one of such operations.)<\/li>\n<li>All custom resource models should be inherited from <strong>\\Magento\\Framework\\Model\\ResourceModel\\Db\\AbstractDb<\/strong> class. It has a method <strong><em>getConnection()<\/em><\/strong> where <strong>\\Magento\\Framework\\App\\ResourceConnection<\/strong> object is called.\n<pre>    public function getConnection()\r\n    {\r\n        $fullResourceName = ($this-&gt;connectionName ? $this-&gt;connectionName : ResourceConnection::DEFAULT_CONNECTION);\r\n        return $this-&gt;resource-&gt;getContent($fullResourceName);\r\n    }\r\n<\/pre>\n<\/li>\n<\/ul>\n<p>The <strong>\\Magento\\Framework\\App\\ResourceConnection<\/strong> contains fields and methods for operating with data from global configuration. It concerns the data from <strong>app\/etc\/env.php<\/strong> file. For example, <strong><em>ResourceConnection::DEFAULT_CONNECTION<\/em><\/strong> is default value and corresponds to <strong><em>[&lsquo;db&rsquo; =&gt; [&lsquo;connection&rsquo; =&gt; [&lsquo;default&rsquo; =&gt; [&hellip;]]]]<\/em><\/strong>:<\/p>\n<pre>'db' =&gt; [\r\n        'table_prefix' =&gt; '',\r\n        'connection' =&gt; [\r\n            'default' =&gt; [\r\n                'host' =&gt; 'localhost',\r\n                'dbname' =&gt; 'magento',\r\n                'username' =&gt; 'root',\r\n                'password' =&gt; '',\r\n                'active' =&gt; '1'\r\n            ]\r\n        ]\r\n    ],\r\n<\/pre>\n<p>(You can create a new custom connection and set it to <strong><em>$connectionName<\/em><\/strong> in your custom resource model.)<\/p>\n<h2 id=\"step_2\">Magento 2 Resource Models<\/h2>\n<p>As mentioned above, the 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.<\/p>\n<p>A resource model extends <strong>\\Magento\\Framework\\Model\\ResourceModel\\Db\\AbstractDb<\/strong> (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).<\/p>\n<p>You need to define the table name and the primary key field name for the resource model because it&rsquo;s necessary to know where to save the model state. They are specified by calling the <strong><em>_init()<\/em><\/strong> method in the protected <strong><em>_construct()<\/em><\/strong> method. Note that you call <strong><em>_init()<\/em><\/strong> from a single-underscore construct method, not the real double-underscore PHP constructor. This single-underscore <strong><em>_construct()<\/em><\/strong> method is also the legacy from Magento 1 and is called by the real <strong><em>__construct()<\/em><\/strong> method inherited from <strong>\\Magento\\Framework\\Model\\ResourceModel<\/strong> class.<\/p>\n<pre>class Inbox extends \\Magento\\Framework\\Model\\ResourceModel\\Db\\AbstractDb\r\n{\r\nprotected function _construct()\r\n{\r\n   $this-&gt;_init('adminnotification_inbox', 'notification_id');\r\n}\r\n&hellip;.\r\n}\r\n---------------------------------------------------------------------\r\nabstract class AbstractDb extends AbstractResource\r\n{\r\n&hellip;.\r\nprotected function _init($mainTable, $idFieldName)\r\n{\r\n   $this-&gt;_setMainTable($mainTable, $idFieldName);\r\n}\r\nprotected function _setMainTable($mainTable, $idFieldName = null)\r\n{\r\n   $this-&gt;_mainTable = $mainTable;\r\n   if (null === $idFieldName) {\r\n       $idFieldName = $mainTable . '_id';\r\n   }\r\n \r\n   $this-&gt;_idFieldName = $idFieldName;\r\n   return $this;\r\n}\r\n&hellip;\r\n}\r\n<\/pre>\n<p>All interacting processes with the database are stored in methods of resource models. They access to database tables using <strong>\\Magento\\Framework\\DB\\Adapter\\Pdo\\Mysql<\/strong> methods. It extends <strong><em>Zend_Db_Adapter_Pdo_Mysql<\/em><\/strong> class and implements <strong>Magento\\Framework\\DB\\Adapter\\AdapterInterface<\/strong>. Here is a mechanism of connection between these classes to resource models:<\/p>\n<ul>\n<li>The <strong>\\Magento\\Framework\\DB\\Adapter\\Pdo\\Mysql<\/strong> object is created in the <strong>Magento\\Framework\\Model\\ResourceModel\\Type\\Db\\Pdo\\Mysql<\/strong> class in the protected method <strong><em>getDbConnectionClassName()<\/em><\/strong>:\n<pre>protected function getDbConnectionClassName()\r\n    {\r\n        return DB\\Adapter\\Pdo\\Mysql::class;\r\n    }\r\n<\/pre>\n<p>It&rsquo;s called in the protected method&nbsp;<em><strong>getDbConnectionInstance()<\/strong><\/em>, which is called in the public method&nbsp;<em><strong>getConnection()<\/strong><\/em>.<\/p><\/li>\n<li>The global configuration file <strong>app\/etc\/di.xml<\/strong> contains a preference:\n<pre class=\"\">    \r\n<\/pre>\n<p>So, <strong>\\Magento\\Framework\\Model\\ResourceModel\\Type\\Db\\Pdo\\Mysql<\/strong> is a realization of <strong><em>ConnectionAdapterInterface<\/em><\/strong>.<\/p><\/li>\n<li>The <strong><em>ConnectionAdapterInterface<\/em><\/strong> is called in <strong>\\Magento\\Framework\\Model\\ResourceModel\\Type\\Db\\ConnectionFactory<\/strong> in the <strong><em>create()<\/em><\/strong> method:\n<pre>public function create(array $connectionConfig)\r\n    {\r\n        \/** @var \\Magento\\Framework\\App\\ResourceConnection\\ConnectionAdapterInterface $adapterInstance *\/\r\n        $adapterInstance = $this-&gt;objectManager-&gt;create(\r\n            \\Magento\\Framework\\App\\ResourceConnection\\ConnectionAdapterInterface::class,\r\n            ['config' =&gt; $connectionConfig]\r\n        );\r\n\r\n        return $adapterInstance-&gt;getConnection();\r\n    }\r\n<\/pre>\n<\/li>\n<li>The <strong>\\Magento\\Framework\\Model\\ResourceModel\\Type\\Db\\ConnectionFactory<\/strong> is a realization of the <strong>\\Magento\\Framework\\Model\\ResourceModel\\Type\\Db\\ConnectionFactoryInterface<\/strong> class. It is called in the <strong>\\Magento\\Framework\\App\\ResourceConnection<\/strong> (which is called in resource model as it was mentioned above, and used in methods for connecting to the database) in the <strong><em>__construct()<\/em><\/strong> method:\n<pre>public function __construct(\r\n        ResourceConfigInterface $resourceConfig,\r\n        ConnectionFactoryInterface $connectionFactory,\r\n        DeploymentConfig $deploymentConfig,\r\n    ) {\r\n        var_dump($resourceConfig);\r\n        $this-&gt;config = $resourceConfig;\r\n        $this-&gt;connectionFactory = $connectionFactory;\r\n        $this-&gt;deploymentConfig = $deploymentConfig;\r\n        $this-&gt;tablePrefix = $tablePrefix ?: null;\r\n    }\r\n<\/pre>\n<\/li>\n<\/ul>\n<p>All transactions, operations with foreign keys, indexes, columns, and tables are implemented in <strong>\\Magento\\Framework\\DB\\Adapter\\Pdo\\Mysql<\/strong>.<\/p>\n<div class=\"module_in_content_container\"><a href=\"https:\/\/belvg.com\/magento-audit\" class=\"link_to_module\" target=\"_blank\" rel=\"noopener\"><\/a><div class=\"module_content\"><div class=\"module_content_part\"><h3 class=\"title\">Magento Audit<\/h3><p class=\"module_content_text\">Take your online store to the next level with BelVG Magento Audit<\/p><a href=\"https:\/\/belvg.com\/magento-audit\" class=\"link_2_to_module\" target=\"_blank\" style=\"display:inline-block\" rel=\"noopener\"><span class=\"read-more\">Visit the page<\/span><\/a><\/div><\/div><\/div>\n<h2 id=\"step_3\">Magento 2 Models<\/h2>\n<p>Models are data and behavior, representing entities. Anything represented by a database table is most likely going to be a model.<\/p>\n<p>To create the model, you just create a class and extend it from <strong>\\Magento\\Framework\\Model\\AbstractModel<\/strong>. Again, note the single-underscore construct method. Do not confuse it with the real PHP constructor. Call the method <strong><em>_init()<\/em><\/strong> where the resource model should be set.<\/p>\n<pre>class Inbox extends \\Magento\\Framework\\Model\\AbstractModel implements NotifierInterface, InboxInterface\r\n{\r\nprotected function _construct()\r\n{\r\n   $this-&gt;_init('Magento\\AdminNotification\\Model\\ResourceModel\\Inbox');\r\n}\r\n&hellip;.\r\n}\r\n-----------------------------------------------------------------------------------\r\nabstract class AbstractModel extends \\Magento\\Framework\\DataObject\r\n{\r\n...\r\nprotected function _init($resourceModel)\r\n{\r\n   $this-&gt;_setResourceModel($resourceModel);\r\n   $this-&gt;_idFieldName = $this-&gt;_getResource()-&gt;getIdFieldName();\r\n}\r\n&hellip;\r\n}\r\n<\/pre>\n<p>This is required to support the inherited <strong>AbstractModel<\/strong> methods <strong><em>getResource()<\/em><\/strong> and <strong><em>getCollection()<\/em><\/strong>.<\/p>\n<p>Method <strong><em>getCollection()<\/em><\/strong> is deprecated. It won&rsquo;t be used in future Magento 2 versions. It&rsquo;s required to use the collection factory instead to avoid conflicts with your code.<\/p>\n<p>The model has no direct access to the database, only the resource models.<\/p>\n<p>Models contain methods only for managing objects with data that is supposed to be prepared for saving to a database or loading to a frontend. Even method load was &ldquo;moved&rdquo; 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 unnecessary transactions to the database if the data in an object hasn&rsquo;t changed. It&rsquo;s used in the method <strong><em>save()<\/em><\/strong> in the <strong>\\Magento\\Eav\\Model\\Entity<\/strong> class, depending on different Magento 2 entities:<\/p>\n<pre>public function save(\\Magento\\Framework\\Model\\AbstractModel $object)\r\n    {\r\n        \/**\r\n         * Direct deleted items to delete method\r\n         *\/\r\n        if ($object-&gt;isDeleted()) {\r\n            return $this-&gt;delete($object);\r\n        }\r\n        if (!$object-&gt;hasDataChanges()) {\r\n            return $this;\r\n        }\r\n        ...\r\n    }<\/pre>\n<p>Besides the&nbsp;<em><strong>load()<\/strong><\/em>&nbsp;method, Magento 2 model also contains the deprecated CRUD (&ldquo;CRUD&rdquo; stands for &ldquo;Create, Read, Update, Delete.&rdquo;) methods&nbsp;<em><strong>save()<\/strong><\/em>&nbsp;and&nbsp;<em><strong>delete()<\/strong><\/em>.&nbsp;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.<\/p>\n<pre>abstract class AbstractModel extends \\Magento\\Framework\\DataObject\r\n{\r\n&hellip;.\r\npublic function save()\r\n{\r\n   $this-&gt;_getResource()-&gt;save($this);\r\n   return $this;\r\n}\r\n&hellip;.\r\n}\r\n\r\nabstract class AbstractDb extends AbstractResource\r\n{\r\n&hellip;.\r\npublic function save(\\Magento\\Framework\\Model\\AbstractModel $object)\r\n{\r\n   if ($object-&gt;isDeleted()) {\r\n       return $this-&gt;delete($object);\r\n   }\r\n<\/pre>\n<p>Actually, the method does both: If the <strong>$isDeleted<\/strong> parameter is specified, it sets the <strong>_isDeleted<\/strong> flag value; otherwise, it returns the current flag value. The method <strong><em>validateBeforeSave()<\/em><\/strong> uses a validator, which contains all the rules to validate the current model. It is called by the resource model <strong><em>save()<\/em><\/strong> method.<\/p>\n<p>In the resource model <strong><em>save()<\/em><\/strong> method, the <strong>_dataSaveAllowed<\/strong> flag can stop saving after the <strong><em>beforeSave()<\/em><\/strong> method was called. This can be helpful in case some data validation failed.&nbsp;The resource models method&nbsp;<em><strong>save()<\/strong><\/em>&nbsp;checks the saved object and runs&nbsp;<em><strong>updateObject()<\/strong><\/em>&nbsp;and&nbsp;<em><strong>saveNewObject()<\/strong><\/em>, which use&nbsp;<strong>\\Magento\\Framework\\DB\\Adapter\\AdapterInterface<\/strong>&nbsp;object for working with databases.&nbsp;Mechanism of the method <em><strong>load()<\/strong><\/em> is similar:<\/p>\n<pre>public function load($modelId, $field = null)\r\n{\r\n   $this-&gt;_beforeLoad($modelId, $field);\r\n   $this-&gt;_getResource()-&gt;load($this, $modelId, $field);\r\n   $this-&gt;_afterLoad();\r\n   $this-&gt;setOrigData();\r\n   $this-&gt;_hasDataChanges = false;\r\n   $this-&gt;updateStoredData();\r\n   return $this;\r\n}\r\n&hellip;.\r\nabstract class AbstractDb extends AbstractResource\r\n{\r\n&hellip;.\r\npublic function load(\\Magento\\Framework\\Model\\AbstractModel $object, $value, $field = null)\r\n{\r\n   if ($field === null) {\r\n       $field = $this-&gt;getIdFieldName();\r\n   }\r\n\r\n   $connection = $this-&gt;getConnection();\r\n   if ($connection &amp;&amp; $value !== null) {\r\n       $select = $this-&gt;_getLoadSelect($field, $value, $object);\r\n       $data = $connection-&gt;fetchRow($select);\r\n\r\n       if ($data) {\r\n           $object-&gt;setData($data);\r\n       }\r\n   }\r\n\r\n   $this-&gt;unserializeFields($object);\r\n   $this-&gt;_afterLoad($object);\r\n\r\n   return $this;\r\n}\r\n&hellip;.\r\n}\r\n<\/pre>\n<p>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.<\/p>\n<p>The <strong><em>_afterLoad()<\/em><\/strong> 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 <strong>model_load_before<\/strong> and <strong>model_load_after<\/strong>, which carries a simple data transfer object. The model instance itself is the key <strong>&ldquo;object&rdquo;<\/strong>.<\/p>\n<div class=\"module_in_content_container\"><a href=\"https:\/\/belvg.com\/magento-development\" class=\"link_to_module\" target=\"_blank\" rel=\"noopener\"><\/a><div class=\"module_content\"><img src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2018\/08\/magento-development-services.png\" width=\"481\" height=\"480\" alt=\"magento development services\" class=\"module_image\" title=\"Magento 2: Models, Resource Models and Collections in 2026\"><div class=\"module_content_part\"><h3 class=\"title\">Magento Development Services<\/h3><p class=\"module_content_text\">Take your online store to the next level with BelVG Magento development<\/p><a href=\"https:\/\/belvg.com\/magento-development\" class=\"link_2_to_module\" target=\"_blank\" style=\"display:inline-block\" rel=\"noopener\"><span class=\"read-more\">Click to visit the page<\/span><\/a><\/div><\/div><\/div>\n<h2 id=\"step_4\">Magento 2 Collections<\/h2>\n<p>Collections are encapsulating sets of models and related functionality, such as filtering, sorting, and paging.<\/p>\n<p>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.<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/07\/databases-in-magento2-configuration.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/07\/databases-in-magento2-configuration.jpg\" alt=\"databases-in-magento2-configuration\" width=\"1109\" height=\"686\" class=\"lazy aligncenter size-full wp-image-25920\" title=\"Magento 2: Models, Resource Models and Collections in 2026\"><\/a><\/p>\n<p>The collection extends <strong>\\Magento\\Framework\\Model\\ResourceModel\\Db\\Collection\\AbstractCollection<\/strong>.<br>\nWhen 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&rsquo;s also necessary to know the matching resource model to be able to access the database. That&rsquo;s why the class names of the model and the resource model are specified by using the <strong><em>_init()<\/em><\/strong> method in the protected <strong><em>_construct()<\/em><\/strong> method.<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/07\/magento-databases-how-to-configure.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2017\/07\/magento-databases-how-to-configure.jpg\" alt=\"magento-databases-how-to-configure\" width=\"1109\" height=\"616\" class=\"lazy aligncenter size-full wp-image-25921\" title=\"Magento 2: Models, Resource Models and Collections in 2026\"><\/a><\/p>\n<p>There isn&rsquo;t the best choice to use the method <strong><em>getCollection()<\/em><\/strong> of <strong>\\Magento\\Framework\\Model\\AbstractModel<\/strong> 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 <strong>\\Magento\\Setup\\Fixtures\\Quote\\QuoteGenerator<\/strong>:<\/p>\n<pre>\/**\r\n  * @var \\Magento\\Catalog\\Model\\ResourceModel\\Product\\CollectionFactory\r\n  *\/\r\nprivate $productCollectionFactory;\r\n\r\n...\r\n\r\npublic function __construct(\r\n        ...\r\n        \\Magento\\Catalog\\Model\\ResourceModel\\Product\\CollectionFactory $productCollectionFactory,\r\n        ...\r\n    ) {\r\n        ...\r\n        $this-&gt;productCollectionFactory = $productCollectionFactory;\r\n        ...\r\n    }\r\n\r\n...\r\n\r\nprivate function getProductIds(\\Magento\\Store\\Api\\Data\\StoreInterface $store, $typeId, $limit = null)\r\n    {\r\n        \/** @var $productCollection \\Magento\\Catalog\\Model\\ResourceModel\\Product\\Collection *\/\r\n        $productCollection = $this-&gt;productCollectionFactory-&gt;create();\r\n        $productCollection-&gt;addStoreFilter($store-&gt;getId());\r\n        $productCollection-&gt;addWebsiteFilter($store-&gt;getWebsiteId());\r\n\r\n        \/\/ \"Big%\" should be replaced with a configurable value.\r\n        if ($typeId === QuoteConfiguration::BIG_CONFIGURABLE_TYPE) {\r\n            $productCollection-&gt;getSelect()-&gt;where(\" type_id = '\" . Configurable::TYPE_CODE . \"' \");\r\n            $productCollection-&gt;getSelect()-&gt;where(\" sku LIKE 'Big%' \");\r\n        } else {\r\n            $productCollection-&gt;getSelect()-&gt;where(\" type_id = '$typeId' \");\r\n            $productCollection-&gt;getSelect()-&gt;where(\" sku NOT LIKE 'Big%' \");\r\n        }\r\n\r\n        return $productCollection-&gt;getAllIds($limit);\r\n    }\r\n<\/pre>\n<p>The API you program against for collections is implemented by <strong>\\Magento\\Framework\\Model\\ResourceModel\\Db\\Collection\\AbstractCollection<\/strong>.<\/p>\n<p>The programmatic API for collections is implemented by <strong>\\Magento\\Framework\\Model\\ResourceModel\\Db\\Collection\\AbstractCollection<\/strong>.<\/p>\n<pre class=\"\">\/\/ Collection provides several useful functions for working with a result\r\n\/\/ set; here is a partial set\r\naddFieldToFilter($field, $condition = null);\r\ngetConnection();\r\ngetSelect();\r\naddBindParam($name, $value);\r\ngetIdFieldName();\r\ndistinct($flag);\r\naddOrder($field, $direction = self::SORT_ORDER_DESC);\r\nsetOrder($field, $direction = self::SORT_ORDER_DESC);\r\nunshiftOrder($field, $direction = self::SORT_ORDER_DESC);\r\ngetItems();\r\ngetSize();\r\ngetSelectCountSql();\r\nload($printQuery = false, $logQuery = false);\r\nresetData();\r\nwalk($callback, array $args = []);\r\n<\/pre>\n<p>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.<\/p>\n<p><a href=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2020\/03\/models-resource-models-and-collections-in-magento-2.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/belvg.com\/wp-content\/uploads\/2019\/06\/pixel.png\" data-src=\"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2020\/03\/models-resource-models-and-collections-in-magento-2.jpg\" alt=\"models, resource models and collections in magento 2\" width=\"1109\" height=\"930\" class=\"lazy aligncenter size-full wp-image-26149\" title=\"Magento 2: Models, Resource Models and Collections in 2026\"><\/a><\/p>\n<p>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 <strong><em>load()<\/em><\/strong> method is explicitly called.<\/p>\n<p>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.<\/p>\n<p>It solves these main issues:<\/p>\n<ul>\n<li>Provides a container for storing collections of objects.<\/li>\n<li>Prevents unnecessary data loading.<\/li>\n<li>Stores all objects during a session.<\/li>\n<li>Provides an interface for filtering and sorting entities of a specific kind.<\/li>\n<\/ul>\n<p>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 detail in the second part of the article.<\/p>\n<h2 id=\"step_5\">Conclusion<\/h2>\n<p>Magento 2 ORM remains the foundation for database interaction in 2026. The core architecture is built around three main components:<\/p>\n<ul>\n<li><strong>Models.<\/strong>&nbsp;They manage entity data and business behavior.<\/li>\n<li><strong>Resource Models.<\/strong>&nbsp;These models handle database operations and CRUD logic.<\/li>\n<li><strong>Collection.<\/strong>&nbsp;It retrieves and filters groups of entities.<\/li>\n<\/ul>\n<p>Modern Magento development favors Service Contracts and Repositories for cleaner and upgrade-safe code. Still, understanding the ORM layer remains important for building custom modules, debugging database operations, and efficiently extending Magento functionality.<\/p>\n<p>Please check the second part of the article:&nbsp;<a href=\"https:\/\/belvg.com\/blog\/database-in-magento-2-service-contracts.html\">Database in Magento 2: Service Contracts<\/a><\/p>\n<p>Looking for an expert <a href=\"https:\/\/belvg.com\/magento-development\" target=\"_blank\" rel=\"noopener\">Magento development team<\/a> to realize your projects? We can help!<\/p>\n<p><em>The following people contributed to the article: Sasha Mitskevich.<\/em><\/p>\n\n","protected":false},"excerpt":{"rendered":"Magento 2 uses an Object-Relational Mapping (ORM) system to manage how application data interacts with &#8230;","protected":false},"author":82,"featured_media":30575,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_acf_changed":false,"footnotes":""},"categories":[14,389,471,524],"tags":[],"class_list":["post-13669","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-magento","category-magento2-development","category-magento-developer","category-magento-speed-optimization","post_format-post-format-image"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"Find out how to work with databases in Magento 2 and how to configure Models, Resource Models, and Collections. Improve your M2 ORM understanding\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Andrey Litvin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#article\",\"name\":\"Magento 2 Database 2026: Models and Collections | BelVG Blog\",\"headline\":\"Magento 2: Models, Resource Models and Collections in 2026\",\"author\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/andrey-litvin#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/image-20.webp\",\"width\":1108,\"height\":590},\"datePublished\":\"2020-03-10T13:50:13+02:00\",\"dateModified\":\"2026-05-12T11:25:30+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":5,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#webpage\"},\"articleSection\":\"Magento, Magento 2 Development, Magento Developer, Magento Speed Optimization, Image\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/belvg.com\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento#listItem\",\"name\":\"Magento\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento#listItem\",\"position\":2,\"name\":\"Magento\",\"item\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#listItem\",\"name\":\"Magento 2: Models, Resource Models and Collections in 2026\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#listItem\",\"position\":3,\"name\":\"Magento 2: Models, Resource Models and Collections in 2026\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/category\\\/magento#listItem\",\"name\":\"Magento\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#organization\",\"name\":\"BelVG Blog\",\"description\":\"Magento and Prestashop articles\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/andrey-litvin#author\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/andrey-litvin\",\"name\":\"Andrey Litvin\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e1a6e3c80cb940fddb65016d94b015cd951b4a8a9cd7227565131f28ea95c7a0?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Andrey Litvin\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#webpage\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html\",\"name\":\"Magento 2 Database 2026: Models and Collections | BelVG Blog\",\"description\":\"Find out how to work with databases in Magento 2 and how to configure Models, Resource Models, and Collections. Improve your M2 ORM understanding\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/andrey-litvin#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/author\\\/andrey-litvin#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/03\\\/image-20.webp\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html\\\/#mainImage\",\"width\":1108,\"height\":590},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/database-in-magento-2-models-resource-models-and-collections.html#mainImage\"},\"datePublished\":\"2020-03-10T13:50:13+02:00\",\"dateModified\":\"2026-05-12T11:25:30+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/belvg.com\\\/blog\\\/\",\"name\":\"BelVG Blog\",\"description\":\"Magento and Prestashop articles\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/belvg.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Magento 2 Database 2026: Models and Collections | BelVG Blog","description":"Find out how to work with databases in Magento 2 and how to configure Models, Resource Models, and Collections. Improve your M2 ORM understanding","canonical_url":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#article","name":"Magento 2 Database 2026: Models and Collections | BelVG Blog","headline":"Magento 2: Models, Resource Models and Collections in 2026","author":{"@id":"https:\/\/belvg.com\/blog\/author\/andrey-litvin#author"},"publisher":{"@id":"https:\/\/belvg.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2020\/03\/image-20.webp","width":1108,"height":590},"datePublished":"2020-03-10T13:50:13+02:00","dateModified":"2026-05-12T11:25:30+02:00","inLanguage":"en-US","commentCount":5,"mainEntityOfPage":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#webpage"},"isPartOf":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#webpage"},"articleSection":"Magento, Magento 2 Development, Magento Developer, Magento Speed Optimization, Image"},{"@type":"BreadcrumbList","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/belvg.com\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/category\/magento#listItem","name":"Magento"}},{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/category\/magento#listItem","position":2,"name":"Magento","item":"https:\/\/belvg.com\/blog\/category\/magento","nextItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#listItem","name":"Magento 2: Models, Resource Models and Collections in 2026"},"previousItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#listItem","position":3,"name":"Magento 2: Models, Resource Models and Collections in 2026","previousItem":{"@type":"ListItem","@id":"https:\/\/belvg.com\/blog\/category\/magento#listItem","name":"Magento"}}]},{"@type":"Organization","@id":"https:\/\/belvg.com\/blog\/#organization","name":"BelVG Blog","description":"Magento and Prestashop articles","url":"https:\/\/belvg.com\/blog\/"},{"@type":"Person","@id":"https:\/\/belvg.com\/blog\/author\/andrey-litvin#author","url":"https:\/\/belvg.com\/blog\/author\/andrey-litvin","name":"Andrey Litvin","image":{"@type":"ImageObject","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/e1a6e3c80cb940fddb65016d94b015cd951b4a8a9cd7227565131f28ea95c7a0?s=96&d=mm&r=g","width":96,"height":96,"caption":"Andrey Litvin"}},{"@type":"WebPage","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#webpage","url":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html","name":"Magento 2 Database 2026: Models and Collections | BelVG Blog","description":"Find out how to work with databases in Magento 2 and how to configure Models, Resource Models, and Collections. Improve your M2 ORM understanding","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/belvg.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#breadcrumblist"},"author":{"@id":"https:\/\/belvg.com\/blog\/author\/andrey-litvin#author"},"creator":{"@id":"https:\/\/belvg.com\/blog\/author\/andrey-litvin#author"},"image":{"@type":"ImageObject","url":"https:\/\/belvg.com\/blog\/wp-content\/uploads\/2020\/03\/image-20.webp","@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html\/#mainImage","width":1108,"height":590},"primaryImageOfPage":{"@id":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html#mainImage"},"datePublished":"2020-03-10T13:50:13+02:00","dateModified":"2026-05-12T11:25:30+02:00"},{"@type":"WebSite","@id":"https:\/\/belvg.com\/blog\/#website","url":"https:\/\/belvg.com\/blog\/","name":"BelVG Blog","description":"Magento and Prestashop articles","inLanguage":"en-US","publisher":{"@id":"https:\/\/belvg.com\/blog\/#organization"}}]}},"aioseo_meta_data":{"post_id":"13669","title":"Magento 2 Database 2026: Models and Collections | #site_title","description":"Find out how to work with databases in Magento 2 and how to configure Models, Resource Models, and Collections. Improve your M2 ORM understanding","keywords":null,"keyphrases":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":null,"twitter_description":null,"schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-11-03 18:37:17","updated":"2026-11-03 18:37:17"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/belvg.com\/blog\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/belvg.com\/blog\/category\/magento\" title=\"Magento\">Magento<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tMagento 2: Models, Resource Models and Collections in 2026\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/belvg.com\/blog\/"},{"label":"Magento","link":"https:\/\/belvg.com\/blog\/category\/magento"},{"label":"Magento 2: Models, Resource Models and Collections in 2026","link":"https:\/\/belvg.com\/blog\/database-in-magento-2-models-resource-models-and-collections.html"}],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts\/13669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/users\/82"}],"replies":[{"embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/comments?post=13669"}],"version-history":[{"count":16,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts\/13669\/revisions"}],"predecessor-version":[{"id":30578,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/posts\/13669\/revisions\/30578"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/media\/30575"}],"wp:attachment":[{"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/media?parent=13669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/categories?post=13669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/belvg.com\/blog\/wp-json\/wp\/v2\/tags?post=13669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}