cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Cayenne Documentation > Caching Query Results
Date Sun, 20 Feb 2011 14:24:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2036/9/1/_/styles/combined.css?spaceKey=CAYDOC&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAYDOC/Caching+Query+Results">Caching
Query Results</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~andrus">Andrus
Adamchik</a>
    </h4>
        <br/>
                         <h4>Changes (5)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The example above shows caching with
{{SelectQuery}}, but it works exactly the same way for {{SQLTemplate}} and {{ProcedureQuery}}.
Similarly {{SHARED_CACHE}} and {{SHARED_CACHE_REFRESH}} cache policies create cache shared
by all ObjectContexts that work on top of a given DataDomain.  <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">There&#39;s
another optional query property called &quot;{{cacheGroups}}&quot; that allows to
fine-tune cache expiration in a declarative fashion. When creating a query, a user would specify
the names of the cache groups (which are really cache _expiration_ groups) associated with
this query, and then separately define expiration policies for the cache groups present in
the application. See [CAYDOC:Query Result Caching] for more details. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. Queries Mapped in CayenneModeler
<br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
easiest way to set up caching is by creating a named query in CayenneModeler with the appropriate
caching type. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Named
queries created in CayenneModeler can also be configured to use caching, with the same cache
strategy and cache groups parameters: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>!caching.jpg! <br>
<br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Then
it can be executed via DataContext: <br> <br>{code} <br>List objects1 =
context.performQuery(&quot;MyQuery&quot;, false); <br>{code} <br> <br>The
second &quot;false&quot; parameter above indicated that if possible, cached result
should be used. Now if we want to force refresh, it can be changed to true (for just this
invocation - this does not affect the underlying saved query) <br> <br>{code}
<br>List objects2 = context.performQuery(&quot;MyQuery&quot;, true); <br>{code}
<br> <br>Note that parameterized named queries will still work correctly with
the cache. We&#39;ve already mentioned that the users must ensure that two queries must
have different names if they fetch logically different data. This is NOT the case with queries
stored in the DataMap. If you run the same named query with different sets of parameters,
Cayenne will internally generate unique cache keys for each distinct parameter set. <br>
<br>{code} <br>Map parameters = Collections.singletonMap(&quot;key&quot;,
&quot;value1&quot;); <br>List objects1 = context.performQuery(&quot;MyQuery&quot;,
parameters, false); <br>{code} <br> <br>Now if we run the same query with
a different set of parameters, Cayenne will do the right thing and create a separate entry
in the cache: <br>{code} <br>Map parameters = Collections.singletonMap(&quot;key&quot;,
&quot;value2&quot;); <br>List objects2 = context.performQuery(&quot;MyQuery&quot;,
parameters, false); <br>{code} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">NamedQueries
that are using caching can be executed just like any other [NamedQuery|CAYDOC:NamedQuery].
<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>Cayenne provides a way to cache query results, avoiding unneeded database
trips for the frequently used queries. Caching strategy is configured per query. A strategy
can be set via API or in CayenneModeler. Possible strategies, as defined in the <tt>org.apache.cayenne.query.QueryCacheStrategy</tt>
enum are the following:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'>Policy</th>
<th class='confluenceTh'>Cache Scope</th>
<th class='confluenceTh'>Cache Behavior</th>
</tr>
<tr>
<td class='confluenceTd'><em>(default)</em> <tt>NO_CACHE</tt>
</td>
<td class='confluenceTd'>N/A</td>
<td class='confluenceTd'>Always fetch, never use cache, never save to cache</td>
</tr>
<tr>
<td class='confluenceTd'><tt>LOCAL_CACHE</tt></td>
<td class='confluenceTd'>ObjectContext</td>
<td class='confluenceTd'>If result is previously cached, use it, otherwise do a fetch
and store result in cache for future use</td>
</tr>
<tr>
<td class='confluenceTd'><tt>LOCAL_CACHE_REFRESH</tt></td>
<td class='confluenceTd'>ObjectContext</td>
<td class='confluenceTd'>Never use cache, always do a fetch and store result in cache
for future use</td>
</tr>
<tr>
<td class='confluenceTd'><tt>SHARED_CACHE</tt></td>
<td class='confluenceTd'>DataDomain (usually shared by all contexts in the same JVM)</td>
<td class='confluenceTd'>If result is previously cached, use it, otherwise do a fetch
and store result in cache for future use</td>
</tr>
<tr>
<td class='confluenceTd'><tt>SHARED_CACHE_REFRESH</tt></td>
<td class='confluenceTd'>DataDomain (usually shared by all contexts in the same JVM)</td>
<td class='confluenceTd'>Never use cache, always do a fetch and store result in cache
for future use</td>
</tr>
</tbody></table>
</div>


<p>It is important to understand that caching of <b>result lists</b> is
done independently from caching of <b>individual DataObjects and DataRows</b>.
Therefore the API is different as well. Also cached results lists are not synchronized across
VMs (even the shared cache).</p>

<h3><a name="CachingQueryResults-APIforResultCaching"></a>API for Result
Caching</h3>

<p>When creating queries in the code, users may set a desired cache strategy per query.
Below we will create a query and set its caching policy to LOCAL_CACHE:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
SelectQuery query = <span class="code-keyword">new</span> SelectQuery(Artist.class);

<span class="code-comment">// set local cache strategy, meaning the cache will be stored
in the ObjectContext 
</span><span class="code-comment">// and not shared between different contexts
</span>query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);

ObjectContext context = ... <span class="code-comment">// assume <span class="code-keyword">this</span>
exists
</span>
<span class="code-comment">// <span class="code-keyword">if</span> there
was no cache at <span class="code-keyword">this</span> point, the query will hit
the database, 
</span><span class="code-comment">// and will store the result in the cache
</span>List objects = context.performQuery(query);
</pre>
</div></div>

<p>Now if we rerun the same query (or create a new instance of the query with the same
set of parameters), we'll get cached result, which will be much faster than fetching it from
DB. </p>

<p>.bq The point about 2 separate queries reusing the same cache entry is worth repeating.
A cache key for each query is automatically generated by Cayenne based on the type of the
query and its parameters (such as qualifier, ordering, etc.). So a query itself does not need
to be cached by the user code for future reuse. New queries can be created as needed.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-comment">// creating a <span class="code-keyword">new</span>
query, same as the previous one
</span>SelectQuery query1 = <span class="code-keyword">new</span> SelectQuery(Artist.class);

<span class="code-comment">// <span class="code-keyword">this</span> will
hit the local cache
</span>List objects1 = context.performQuery(query1);
</pre>
</div></div>

<p>Or if we want to refresh the cache, but still keep caching the result after that:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">query1.setCachePolicy(QueryCacheStrategy.LOCAL_CACHE_REFRESH);
List objects2 = context.performQuery(query1);
</pre>
</div></div>

<p>The example above shows caching with <tt>SelectQuery</tt>, but it works
exactly the same way for <tt>SQLTemplate</tt> and <tt>ProcedureQuery</tt>.
Similarly <tt>SHARED_CACHE</tt> and <tt>SHARED_CACHE_REFRESH</tt>
cache policies create cache shared by all ObjectContexts that work on top of a given DataDomain.
</p>

<p>There's another optional query property called "<tt>cacheGroups</tt>"
that allows to fine-tune cache expiration in a declarative fashion. When creating a query,
a user would specify the names of the cache groups (which are really cache <em>expiration</em>
groups) associated with this query, and then separately define expiration policies for the
cache groups present in the application. See <a href="/confluence/display/CAYDOC/Query+Result+Caching"
title="Query Result Caching">Query Result Caching</a> for more details.</p>

<h3><a name="CachingQueryResults-QueriesMappedinCayenneModeler"></a>Queries
Mapped in CayenneModeler</h3>

<p>Named queries created in CayenneModeler can also be configured to use caching, with
the same cache strategy and cache groups parameters:</p>

<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/10508/caching.jpg?version=2&amp;modificationDate=1139788141000"
style="border: 0px solid black" /></span></p>

<p>NamedQueries that are using caching can be executed just like any other <a href="/confluence/display/CAYDOC/NamedQuery"
title="NamedQuery">NamedQuery</a>.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAYDOC/Caching+Query+Results">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=10508&revisedVersion=17&originalVersion=16">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAYDOC/Caching+Query+Results?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message