Entity manager is the primary access point to ORM functionality provided by Doctrine.
EntityManager
is a Doctrine class that lives inDoctrine\ORM
namespace and used to retrieve entities from their repositories using search criteria and save entities back to database.
EntityManager
is registered as a service in the Zend Framework 3 service manager.
In your factory class, you retrieve the EntityManager
from service manager as
follows (if you need a different connection than orm_default
, just replace the orm_default
with
the required connection name):
// Get Doctrine entity manager
$entityManager = $container->get('doctrine.entitymanager.orm_default');
The most used methods provided by the EntityManager
class are listed in table 12.4 below.
Method | Description |
---|---|
persist($entity) |
Places new entity into entity manager (makes it managed). |
remove($entity) |
Removes an entity from database. |
flush() |
Flushes all changes to objects that have been queued up to now to the database. |
createQuery($dql) |
Creates a new Query object. |
getRepository($entityName) |
Gets the repository for an entity class. |
Let's review the methods from table 12.4.
To add a newly created entity to entity manager (to make the entity "managed"), you use
entity manager's persist()
method.
To remove an entity from database, you use entity manager's remove()
method.
When you call persist()
or remove()
, EntityManager
remembers your changes in memory, but doesn't
apply changes to database automatically (by performance reasons). To apply changes to database in a
single transaction, you use the flush()
method.
For example, look at the code example below that shows how to create an instance of the Post
entity
and save it to database:
// Create new Post entity.
$post = new Post();
$post->setTitle('Top 10+ Books about Zend Framework 3');
$post->setContent('Post body goes here');
$post->setStatus(Post::STATUS_PUBLISHED);
$currentDate = date('Y-m-d H:i:s');
$post->setDateCreated($currentDate);
// Add the entity to entity manager.
$entityManager->persist($post);
// Apply changes to database.
$entityManager->flush();
The createQuery()
method of the entity manager is designed for creating a query from a DQL string. It returns the Query
object. You then execute the query and get results (an array of entities matching search conditions).
The getRepository()
method of the entity manager is designed to get repository by entity class name. Please look
below for example where we get the repository for our Post
entity:
$repository = $entityManager->getRepository(Post::class);
Conceptually, each entity class has its own repository. The repository provides methods for retrieving
entities from database. The repository can be considered as a collection of all
available entities of certain class. For example, there are repositories for our Post
, Comment
,
and Tag
entities.
To load data from the database, you retrieve an entity from its repository. When you request the repository for an entity, it loads the data from the table mapped to the entity, and assigns entity's fields with the data.
The
Doctrine\ORM\EntityRepository
class implements the default repository. If needed, you can, by extending theEntityRepository
, create your own repository for certain entity class. We will show how to do that later.
The most used methods provided by the EntityRepository
class are listed in table 12.5.
Method | Description |
---|---|
findAll() |
Finds all entities in the repository. |
find($id) |
Finds an entity by its identifier. |
findBy($criteria, $orderBy, $limit, $offset) |
Finds entities by a set of criteria. |
findOneBy($criteria, $orderBy) |
Finds a single entity by a set of criteria. |
createQueryBuilder($alias) |
Creates a new QueryBuilder instance that is prepopulated for this entity name. |
The findAll()
method gets all entities from repository. For simple example of its usage, look below:
// Find all posts from repository
$posts = $entityManager->getRepository(Post::class)->findAll();
The find()
method is the simplest method of searching for an entity. It retrieves an entity
by its ID (primary key).
In the example below, we select post with ID = 1.
// Find post by primary key (ID)
$post = $entityManager->getRepository(Post::class)->find(1);
The findBy()
takes a search criteria (and optional sorting order and limit)
arguments and returns a collection of entities matching criteria. The findOneBy()
method is very
similar to findBy()
, but it returns the first entity matching the criteria.
In the code example below, we use the findBy()
method for selecting 50 most recent published posts:
// Find 50 most recent published posts
$posts = $entityManager->getRepository(Post::class)->findBy(
['status'=>Post::STATUS_PUBLISHED],
['dateCreated'=>'DESC'], 50);
For your convenience, the EntityRepository
class also provides magic methods allowing you to query entities by attribute name
with the findByX
and findOneByX
methods, as follows (just substitute the X placeholder with an attribute name):
// Query a single post by ID attribute
$post = $entityManager->getRepository(Post::class)->findOneById(1);
// Query posts by status attribute
$posts = $entityManager->getRepository(Post::class)
->findByStatus(Post::STATUS_PUBLISHED);
And the most complex search method is the createQueryBuilder()
. That method allows to create
complex DQL queries.
If standard find methods are not sufficient (or if you have complex search criteria and DQL queries),
you can create your own repository by extending the standard EntityRepository
class
and encapsulate the search logic there. We will show how to do that later when implementing tag cloud feature
for our Blog sample.