In the previous article you learned how to create new tables in Magento 2 database. In this one, you will learn more about the models used to work with the Magento 2 database which allows you to read, edit and delete the data. 

Magento 2 and Magento 1 uses the Model/ResourceModel/Collection ORM (Object-relational mapping) for these purposes. To implement this concept you need to create 3 files (model, resource model, collection).

1. Create the Model file:


add the following code to it:

namespace VendorName\ModuleName\Model;
class Somemodel extends \Magento\Framework\Model\AbstractModel
    protected function _construct()

The _construct initializes the resource model. Pass the name of the resource model class (create it in the next step) to the _init method.

Model is what you will most often work with. This class must be inherited from \Magento\Framework\Model\AbstractModel or its child models. It is responsible for working on one record in the table. The most commonly used methods in this class are:

Load methods:

load($id) - loads an entry whose primary key equals $id;
load($value, $columnName) - loads an entry whose column value $columnName equals $value;

Getters and setters methods:

getSomeKey() - gets the value for the property (column) some_key;
getData('some_key') - analog of getSomeKey;
setSomeKey($value) - sets the value for the property (column) some_key;
setData('some_key', $value) - analog of setSomeKey;
getId() - gets the value of the primary key;
setId($id) - set the value of the primary key;

Saving and deleting methods:

save() - saves data to the database. If the primary key is not specified, creates a new entry;
delete() - deletes an entry whose key matches the key of the model object;

Other methods:

getCollection() - returns the collection object;
getResource() - returns the resource model object;

You can learn about additional methods by exploring the following classes:

2. Create the Resource Model class:


add the following code to it:

namespace VendorName\ModuleName\Model\ResourceModel;
class Somemodel extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
    protected function _construct()
    {         $this->_init('table_name_without_prefix', 'primary_column_name');     }

table_name_without_prefix - the table name in the Magento 2 database without prefix;
primary_column_name - the name of the field in this table with the primary key and autoincrement.

The loading and saving methods in the model work with the database through the resource model.  

3. Create Collection file:


add the following code to it:

namespace VendorName\ModuleName\Model\ResourceModel\Somemodel;
class Collection
    extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
    protected function _construct()
    {         parent::_construct();
        );     }

You must pass model and resources model class names to the _init method.

The collection is responsible for downloading several entries from the table. The most commonly used methods in this class are:

addFieldToFilter($field, $condition) - adds "WHERE $ field = $ condition" constraint;
addFieldToSelect($field) - defines which columns to include in the query. By default, all columns are included in the query;
setOrder($field, $direction) - indicates "ORDER BY $ field $ direction" sorting;
setPageSize($size) - indicates the "LIMIT $ size" restriction;
setCurPage($page) - sets the page number;

Learn about other methods by exploring the following classes:

Example of working with a collection:

$collection = $this->collectionFactory->create();
$collection->addFieldToFilter('status', 1)
    ->addFieldToFilter('publish_date', ['lteq' => '2017-11-01'])
foreach ($collection as $item) {
    echo $item->getName();

This code executes queries to the database and receives the first 10 entries, in which the status column equals 1 and publish_date is less than or equal to 2017-11-01. Then, this code displays the value of the 'name' column for each received entry in a loop.

In the examples, we develop a module for FAQs. You can view the changed code on GitHub.