Doctrine Cache in Mezzio and Dotkernel
source link: https://www.dotkernel.com/how-to/doctrine-cache-in-mezzio-and-dotkernel/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Doctrine caching in DotKernel
Using an ORM in production without any sort of cache strategy is a very bad move. The Database server chokes; lots of CPU cycles wasted only to generate metadata and queries over and over again at each request; the system slows down and so on.
Following Doctrine documentation , we choose to configure doctrine cache system through psr/container.
The main parts we are going to use are query_cache
, metadata_cache
and result_cache
.
As cache type we choose PhpFileCache
and for result cache we are setting a lifetime of 3600 seconds.
Configuration
In the file: config/autoload/doctrine.global.php add the below entry:
'doctrine' => [ 'cache' => [ \Doctrine\Common\Cache\PhpFileCache::class => [ 'class' => \Doctrine\Common\Cache\PhpFileCache::class, 'directory' => getcwd() . '/data/cache/doctrine' ] ] ], 'resultCacheLifetime' => 3600
In the file: config/autoload/local.php add the below entry in the doctrine
section:
'configuration' => [ 'orm_default' => [ // it is recommended to disable doctrine cache on development // just comment any type of cache you dont want to be applied on development 'query_cache' => \Doctrine\Common\Cache\PhpFileCache::class, 'metadata_cache' => \Doctrine\Common\Cache\PhpFileCache::class, 'result_cache' => \Doctrine\Common\Cache\PhpFileCache::class ] ],
Metadata Cache
Your class metadata is being parsed on each request. Instead of parsing this information we should cache it using one of the cache drivers.
We enabled this by adding the following metadata_cache
key to our doctrine configuration:
'doctrine' => [ 'configuration' => [ 'orm_default' => [ 'metadata_cache' => \Doctrine\Common\Cache\PhpFileCache::class, ] ] ]
Query Cache
It is highly recommended that in a production environment you cache the transformation of a DQL query to its SQL counterpart.
It doesn’t make sense to do this parsing multiple times as it doesn’t change unless you alter the DQL query.
We enabled this by adding the following query_cache
key to our doctrine configuration:
'doctrine' => [ 'configuration' => [ 'orm_default' => [ 'query_cache' => \Doctrine\Common\Cache\PhpFileCache::class, ] ] ]
Usage
$query = $em->createQuery('select u from \Entities\User u'); $query->useQueryCache(true);
Result Cache
The result cache can be used to cache the results of your queries so that doctrine don’t have to query the database or hydrate the data again after the first time.
We enabled this by adding the following result_cache
key to our doctrine configuration:
'doctrine' => [ 'configuration' => [ 'orm_default' => [ 'result_cache' => \Doctrine\Common\Cache\PhpFileCache::class, ] ] ]
Usage
$query = $em->createQuery('select u from \Entities\User u'); $query->enableResultCache();
Note: You can set a lifetime
for result cache to live before it will be rewrite by simply passing the value as the first argument:
$query->enableResultCache( $resultCacheLifetime);
Note: You can set a custom ID
for the result cache which is automatically generated for you if you don’t set a custom ID yourself:
$query->enableResultCache( $resultCacheLifetime, 'my_custom_id');
Dotkernel Admin Example
Below there is the code used in Dotkernel Admin in order to list all Admins.
Is using both query_cache
and result_cache
.
$qb = $this->getEntityManager()->createQueryBuilder(); $qb->select('admin') ->from(Admin::class, 'admin'); if (!is_null($search)) { $qb->where($qb->expr()->like('admin.identity', ':search')) ->setParameter('search', '%' . $search . '%'); } $qb->setFirstResult($offset) ->setMaxResults($limit); $qb->orderBy('admin.' . $sort, $order); return $qb->getQuery()->useQueryCache(true)->enableResultCache($this->getCacheLifetime())->getResult();
How to return Collections
For returning collections that extends Doctrine Paginator (Doctrine\ORM\Tools\Pagination\Paginator
) just enable result and/or query cache before passing query builder to collection
$qb = $this->getEntityManager()->createQueryBuilder(); $qb->select('collection') ->from(MyCollection::class, 'collection'); $qb->setFirstResult($offset) ->setMaxResults($limit); $qb->getQuery()->enableResultCache($this->getCacheLifetime())->useQueryCache(true); return new MyCollection($qb);
and the MyCollection look like:
<?php use Doctrine\ORM\Tools\Pagination\Paginator; /** * Class MyCollection * @package Core\Collection */ class MyCollection extends Paginator { }
References
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK