This is a memo regarding a project using the EC-CUBE e-commerce framework, where I re-evaluated the caching mechanisms.
The starting point was that `deleteByPrefix`, which was used to delete caches by prefix in Doctrine 1.x, was no longer available.
Here's a summary of the changes related to caching (English text as is):
## Cache Changes
- Renamed old AbstractCache to CacheProvider
- Dropped the support to the following functions of all cache providers:
- CacheProvider::deleteByWildcard
- CacheProvider::deleteByRegEx
- CacheProvider::deleteByPrefix
- CacheProvider::deleteBySuffix
- CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid
- CacheProvider::flushAll will remove ALL entries, namespaced or not
- Added support to MemcachedCache
- Added support to WincacheCacheSo, the `deleteByXXX` functions were all removed.
This means that when using Result Cache, the method of managing IDs with prefixes for forward-matching deletion is no longer usable.
Well, it means we should manage caches properly using namespaces instead of just IDs.
You can clear caches (`deleteAll`) for each namespace.
This time, I'd like to explain how to use Result Cache. For information on other caches, please refer to the following:
Official(English)::doctrine-project -- Caching
SETTING UP RESULT CACHE IN SYMFONY
Official(English)::Configuration Reference -- Cache Driver
While various customizations are possible, I'll use the example from GitHub as is.
doctrine:
orm:
auto_generate_proxy_classes: false
metadata_cache_driver:
type: pool
pool: doctrine.system_cache_pool
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.systemOnce the above is added to `doctrine.yaml`, the configuration is complete.
USING RESULT CACHE
Result Cache can cache the results of DQL queries. By creating a DQL query, related methods become available.
// Case Repository (extends ServiceEntityRepository)
$qb = $this->createQueryBuilder('user')
->where('user.id = :id')
->setParameter('id', $userId);
$qb->getQuery()
->useResultCache(true, 600, 'UserInfo')
->getResult();After the DQL query is created with `getQuery()`, related methods become available.
We use `useResultCache` to store data in the Result Cache.
https://doctrine2.readthedocs.io/en/latest/reference/caching.html
Since we haven't specified a namespace yet, caches without a namespace will be created.
For example, if `deleteAll` is executed without specifying a namespace, all caches without a namespace will be deleted.
DELETING RESULT CACHE
Here's how to delete Result Cache. There are `delete($id)` and `deleteAll` methods.
// Case Repository (extends ServiceEntityRepository)
$qb = $this->getEntityManager()->createQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->delete('UserInfo');In the example above, the cache with the ID 'UserInfo' will be deleted. It's simple, isn't it?
Now, let's look at my main topic for this article: how to collectively delete only specific caches.
In Doctrine 1.x, we used to add a prefix to the ID and delete caches by forward-matching using `deleteByPrefix()`.
Since that method is no longer available, we'll manage caches using namespaces.
MANAGING RESULT CACHE USING NAMESPACES
Simply put, it's about creating a 'box' called a namespace and storing caches within it.
This is useful when you have multiple projects, or want to categorize caches, such as for 'User' or 'Admin'.
// Case Repository (extends ServiceEntityRepository)
// use ResultCashe in namespace "User"
$qb = $this->createQueryBuilder('user')
->where('user.id = :id')
->setParameter('id', $userId)
->getQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->setNamespace('User');
$result = $qb->useResultCache(true, 600, 'UserInfo')
->getResult();
// DeleteAll namespace "User"
$qb = $this->getEntityManager()->createQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->setNamespace('User');
$cacheDriver->deleteAll();We call the cache driver and set a namespace for the DQL query using `setNamespace()`.
If `deleteAll` is executed with the code above, all caches within the 'User' namespace will be deleted.
This concludes a brief overview of how to use Result Cache and set up namespaces.
For more detailed information, I recommend checking the URLs mentioned in the article.
Recommended Symfony Books
There aren't many varieties, and the framework itself has a vast amount of information, so even introductory books can be quite substantial reads.
📦