Caching is extensively used for optimizing database applications and effectively reducing traffic between the database and the application.
ColdFusion ORM supports two levels of caching:
Objects that are loaded from the database are always cached in the ORM Session as long as the session is open. When EntityLoad is called to retrieve an object in a session for the first time, ORM fetches the data from the database and constructs the object. In any subsequent call to load the same object in the same session, ORM fetches the object from the session cache. To forcefully retrieve the object from the database, EntityReload should be called on the object.
For more details on ORM Sessions and its lifecycle, see ORM session management and Architecture.
ColdFusion provides the ability to store the data that is retrieved from the database in secondary cache. The contents in secondary cache live longer than the life-time of a session. It can also be the life-time of the process or in-definite (disk-caching), depending on the ability of the secondary cache provider. The cache can also be used in a distributed environment depending on the ability of the secondary cache provider.
An important difference between session level cache and secondary level cache is that the session level caches the whole object but the secondary level caches only the data.
Secondary level cache can be leveraged by using an external cache provider with ColdFusion ORM. EHCache , JBossCache, OSCache, SwarmCache, and Tangosol Coherence Cache are some popular secondary cache providers, which can be plugged into Hibernate.
ColdFusion uses EHCache as the default secondary cache provider. EHCache is a distributed caching solution that supports memory and disk-based caching. EHCache can be configured using a configuration file. Different cache regions can be defined in the configuration file. Each cache region has its own configuration that specifies details including the number of elements it can store, eviction policy, time to live ( ttl ), and idle time.
ehcache .xml is available in the following location: CF_root\lib\. For details of the properties in the ehcache . xml , refer to the documentation available at the following URL:
http://ehcache.org/
The following is a sample EHCache configuration file ( ehcache .xml):
<ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="Artist" maxElementsInMemory="20" eternal="true" overflowToDisk="false" /> </ehcache>
ehCache.xml includes the following configuration properties:
diskExpiryThreadIntervalSeconds: The number of seconds between runs of the disk expiry thread. The default value is 120seconds.
The functions cacheGetProperties and cacheSetProperties can be used to get/set these properties.
To use secondary cache, you must configure the following settings in the application:
In this case, the data of the persistent object is cached. It will not cache the associations or associated object's data. To enable this flag on a persistent CFC, specify the following attributes on the component.
cachename : Defines the name of the cache region to be used by the secondary cache provider. If you do not specify a region name for the component, the entity name of the component is considered as the cache name. In case a region is not specified in the configuration file, a region is automatically created with the default configuration.
For example:
<cfcomponent persistent="true" schema="APP" table="Artists" cachename="artist" cacheuse="read-only">
In this case, the primary key of the associated objects are cached. It does not cache the objects loaded as part of the association unless caching is enabled for those objects. To cache an association, specify the following attributes on the association property.
cachename : Defines the name of the cache region to be used by the secondary cache provider. If you do not specify a region name for the association property, the <comoponent_name>.<property_name> is considered as the cache name. In case a region is not specified in the configuration file, a region is automatically created with the default configuration.
For example:
<cfproperty name="art" fieldtype="one-to-many" cfc="CArt" fkcolumn="ArtID" cachename="ArtistArts" cacheuse="read-only">
In this case, the results of queries that are executed by ORMExecuteQuery() or EntityLoad() methods are cached in the secondary cache. To enable caching query data, pass "cacheable=true" and "cachename='cachename' values in the options struct of the methods. If you do not specify the cachename, the query is cached in the default query cache. It is recommended that you to specify the cachename so that you can control eviction.
For example:
availableArts = ORMExecuteQuery("from CArt where issold=0", {}, false, {cacheable=true, cachename="availableArtsQuery"});
Step 1: Set the following in Application.cfc:
<cfset this.name="Caching_Example"> <cfset this.datasource="cfartgallery"> <cfset this.ormenabled="true"> <cfset this.ormsettings.secondarycacheEnabled=true> <cfset this.ormsettings.cacheProvider= "ehcache"> <cfset this.ormsettings.cacheConfig="ehcache.xml">
Step 2: Define the cache settings in the CFCs.
CArtist.cfc
<cfcomponent persistent="true" schema="APP" table="Artists" cachename="artist" cacheuse="read-only"> <cfproperty name="artistid" fieldtype="id"/> <cfproperty name="firstname"/> <cfproperty name="lastname"/> <cfproperty name="state"/> <cfproperty name="art" fieldtype="one-to-many" cfc="CArt" fkcolumn="ArtID" cachename="ArtistArts" cacheuse="read-only"> </cfcomponent>
CArt.cfc
<cfcomponent persistent="true" schema="APP" table="Art"> <cfproperty name="artid" generator="identity" fieldtype="id"/> <cfproperty name="artname"/> <cfproperty name="issold"/> </cfcomponent>
Step 3:
<cfscript>
//This will cache the Artist Component and also the association. It wouldn't cache the Art objects.
artistObj = EntityLoad("CArtists", 3, true);
//This will cache the query.
availableArts = ORMExecuteQuery("from CArt where issold=0", {}, false, {cacheable=true, cachename="availableArtsCache"});
</cfscript>
ColdFusion provides the following methods to evict contents from the secondary cache.
ORMEvictEntity("<component_name>", [primarykey])
This method is used to evict items for the given component name, from the secondary cache. If the primary key is specified, then the data of the entity with that primary key is evicted. Primary key should be a value in case of simple primary key or should be a struct in case of composite primary key.
Example:
<cfset ORMEvictEntity("CArtists")>
Evicts all the cache data of CArtist entity.
<cfset ORMEvictEntity("CArtists", 1)>
Evict the association or collection data of collection art belonging to the component CArtists with primary key 1.
ORMEvictQueries([cachename])
This method is used to evict the data of all the queries from the default query cache. If cache name is specified, then, the data of all the queries belonging to the cache region with the given cache name are evicted. Example:
<cfset ORMEvictCollection("CArtists", "art")>
Evicts all the association or collection data of collection art belonging to the component CArtists.
<cfset ORMEvictCollection("CArtists", "art", 1)>
Evict the association or collection data of collection art belonging to the component CArtists with primary key 1.
ORMEvictQueries([cachename])
This method is used to evict the data of all the queries from the default query cache. If cache name is specified, then, the data of all the queries belonging to the cache region with the given cache name are evicted. Example:
<cfset ORMEvictQueries()>
Evicts the data of all the queries from the default query cache.
<cfset ORMEvictQueries("availableArtsCache")>
Evicts the data of all the queries from the cache region with the name availableArtsCache.
Except in cacheSetProperties and cacheGetProperties , user-defined caches are supported in all caching functions.
Edit ehCache. xml ( cfroot /lib)to set the properties for user-defined caches as shown in the following example:
<!--- item to put in user-defined cache ---> <cfset currentTime = Now()> <!--- put item in user-defined cache ---> <cfset timeToLive=createtimespan(0,0,0,30)> <cfset timeToIdle=createtimespan(0,0,0,30)> <cfset customCache = "usercache"> <cfset id = "cache1"> <cfset cachePut(id,currentTime,timeToLive,timeToIdle,customCache)> <!-- list items in the cache ---> List Items in cache: <cfset cacheIds = cacheGetAllIds(customCache)> <cfdump var="#cacheIds#"><br> <!--- print cache data ---> <cfset cachedData = cacheGet(id,customCache)> <cfoutput>#cachedData#</cfoutput> <!--- print cache metadata ---> Cache metadata: <cfset mdata = cacheGetMetadata(id,"object",customCache)> <cfdump var="#mdata#"> <!--- clear user-defined cache ---> <cfset cacheRemove(ArrayToList(cacheIds),true,customCache)>
Sign in to your account