1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <title>Retrieving Multiple Objects</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
9    <link rel="start" href="index.html" title="Getting Started with Berkeley DB" />
10    <link rel="up" href="persist_access.html" title="Chapter��5.��Saving and Retrieving Objects" />
11    <link rel="prev" href="simpleget.html" title="Retrieving Objects from an Entity Store" />
12    <link rel="next" href="dpl_entityjoin.html" title="Join Cursors" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Retrieving Multiple Objects</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="simpleget.html">Prev</a>��</td>
22          <th width="60%" align="center">Chapter��5.��Saving and Retrieving Objects</th>
23          <td width="20%" align="right">��<a accesskey="n" href="dpl_entityjoin.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="sect1" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title" style="clear: both"><a id="getmultiple"></a>Retrieving Multiple Objects</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <dl>
38          <dt>
39            <span class="sect2">
40              <a href="getmultiple.html#dpl_cursor_initialize">Cursor Initialization</a>
41            </span>
42          </dt>
43          <dt>
44            <span class="sect2">
45              <a href="getmultiple.html#dpl_dups">Working with Duplicate Keys</a>
46            </span>
47          </dt>
48          <dt>
49            <span class="sect2">
50              <a href="getmultiple.html#dpl_cursor_range">Key Ranges</a>
51            </span>
52          </dt>
53        </dl>
54      </div>
55      <p>
56                    It is possible to iterate over every object referenced
57                    by a specific index. You may want to do this if, for
58                    example, you want to examine or modify every object
59                    accessible by a specific primary index. 
60            </p>
61      <p>
62                   In addition, some indexes result in the retrieval of multiple
63                   objects. For example, <code class="literal">MANY_TO_ONE</code>
64                   secondary indexes can result in more than one object for any given
65                   key (also known as <span class="emphasis"><em>duplicate keys</em></span>). 
66                   When this is the case, you must iterate
67                   over the resulting set of objects in order to examine
68                   each object in turn.
69           </p>
70      <p>
71                   There are two ways to iterate over a collection of
72                   objects as returned by an index. One is to use a
73                   standard Java <code class="classname">Iterator</code>, which you
74                   obtain using an <code class="classname">EntityCursor</code>,
75                   which in turn you can obtain from a <code class="classname">PrimaryIndex</code>:
76           </p>
77      <pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
78    store.getPrimaryIndex(String.class, SimpleEntityClass.class);
79EntityCursor&lt;SimpleEntityClass&gt; pi_cursor = pi.entities();
80try {
81    Iterator&lt;SimpleEntityClass&gt; i = pi_cursor.iterator();
82    while (i.hasNext()) {
83        // Do something here
84    }
85} finally {
86    // Always close the cursor
87    pi_cursor.close();
88} </pre>
89      <p>
90                    Alternatively, you can use a Java "foreach" statement
91                    to iterate over object set:
92            </p>
93      <pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
94    store.getPrimaryIndex(String.class, SimpleEntityClass.class);
95EntityCursor&lt;SimpleEntityClass&gt; pi_cursor = pi.entities();
96try {
97    for (SimpleEntityClass seci : pi_cursor) {
98        // do something with each object "seci"
99    }
100// Always make sure the cursor is closed when we are done with it.
101} finally {
102    sec_cursor.close();
103} </pre>
104      <div class="sect2" lang="en" xml:lang="en">
105        <div class="titlepage">
106          <div>
107            <div>
108              <h3 class="title"><a id="dpl_cursor_initialize"></a>Cursor Initialization</h3>
109            </div>
110          </div>
111        </div>
112        <p>
113                            When a cursor is first opened, it is not
114                            positioned to any value; that is,
115                            it is not <span class="emphasis"><em>initialized</em></span>.
116                            Most of the <code class="classname">EntityCursor</code>
117                            methods that move a cursor will initialize it
118                            to either the first or last object, depending
119                            on whether the operation is moving the cursor
120                            forward (all <code class="literal">next...</code>
121                            methods) or backwards (all
122                            <code class="literal">prev...</code>) methods.
123                    </p>
124        <p>
125                            You can also force a cursor, whether it is
126                            initialized or not, to return the first object
127                            by calling
128                            <code class="methodname">EntityCursor.first()</code>.
129                            Similarly, you can force a return of the last
130                            object using
131                            <code class="methodname">EntityCursor.last()</code>.
132                    </p>
133        <p>
134                            Operations that do not move the cursor (such as
135                            <code class="methodname">EntityCursor.current()</code>
136                            or <code class="methodname">EntityCursor.delete()</code>
137                            will throw an 
138                            <code class="classname">IllegalStateException</code>
139                            when used on an uninitialized cursor.
140                    </p>
141      </div>
142      <div class="sect2" lang="en" xml:lang="en">
143        <div class="titlepage">
144          <div>
145            <div>
146              <h3 class="title"><a id="dpl_dups"></a>Working with Duplicate Keys</h3>
147            </div>
148          </div>
149        </div>
150        <p>
151                   If you have duplicate secondary keys, you can return an
152                   <code class="classname">EntityIndex</code> class object for them
153                   using <code class="methodname">SecondaryIndex.subIndex()</code>
154                   Then, use that object's
155                   <code class="methodname">entities()</code>
156                   method to obtain an <code class="classname">EntityCursor</code>
157                   instance.
158           </p>
159        <p>
160                   For example:
161           </p>
162        <pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
163    store.getPrimaryIndex(String.class, SimpleEntityClass.class);
164
165SecondaryIndex&lt;String,String,SimpleEntityClass&gt; si = 
166    store.getSecondaryIndex(pi, String.class, "sKey");
167
168EntityCursor&lt;SimpleEntityClass&gt; sec_cursor = 
169    si.subIndex("skeyone").entities(); 
170
171try {
172for (SimpleEntityClass seci : sec_cursor) {
173        // do something with each object "seci"
174    }
175// Always make sure the cursor is closed when we are done with it.
176} finally {
177    sec_cursor.close(); } </pre>
178        <p>
179                Note that if you are working with duplicate keys, you can
180                control how cursor iteration works by using the following
181                <code class="classname">EntityCursor</code> methods:
182        </p>
183        <div class="itemizedlist">
184          <ul type="disc">
185            <li>
186              <p>
187                                <code class="methodname">nextDup()</code>
188                        </p>
189              <p>
190                            Moves the cursor to the next object with the
191                            same key as the cursor is currently
192                            referencing. That is, this method returns the
193                            next duplicate object. If no such object
194                            exists, this method returns
195                            <code class="literal">null</code>.
196                        </p>
197            </li>
198            <li>
199              <p>
200                                <code class="methodname">prevDup()</code>
201                        </p>
202              <p>
203                            Moves the cursor to the previous object with the
204                            same key as the cursor is currently
205                            referencing. That is, this method returns the
206                            previous duplicate object in the cursor's set
207                            of objects. If no such object exists, this method returns
208                            <code class="literal">null</code>.
209                        </p>
210            </li>
211            <li>
212              <p>
213                                <code class="methodname">nextNoDup()</code>
214                        </p>
215              <p>
216                            Moves the cursor to the next object in the
217                            cursor's set that has a key which is different
218                            than the key that the cursor is currently
219                            referencing.  That is, this method skips all
220                            duplicate objects and returns the
221                            next non-duplicate object in the cursor's set
222                            of objects. If no such object exists, this method returns
223                            <code class="literal">null</code>.
224                        </p>
225            </li>
226            <li>
227              <p>
228                                <code class="methodname">prevNoDup()</code>
229                        </p>
230              <p>
231                            Moves the cursor to the previous object in the
232                            cursor's set that has a key which is different
233                            than the key that the cursor is currently
234                            referencing.  That is, this method skips all
235                            duplicate objects and returns the
236                            previous non-duplicate object in the cursor's set
237                            of objects. If no such object exists, this method returns
238                            <code class="literal">null</code>.
239                        </p>
240            </li>
241          </ul>
242        </div>
243        <p>
244                   For example:
245           </p>
246        <pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
247    store.getPrimaryIndex(String.class, SimpleEntityClass.class);
248
249SecondaryIndex&lt;String,String,SimpleEntityClass&gt; si = 
250    store.getSecondaryIndex(pi, String.class, "sKey");
251
252EntityCursor&lt;SimpleEntityClass&gt; sec_cursor = 
253    si.subIndex("skeyone").entities(); 
254
255try {
256    SimpleEntityClass sec;
257    Iterator&lt;SimpleEntityClass&gt; i = sec_cursor.iterator();
258    while (sec = i.nextNoDup() != null) {
259        // Do something here
260    }
261// Always make sure the cursor is closed when we are done with it.
262} finally {
263    sec_cursor.close(); } </pre>
264      </div>
265      <div class="sect2" lang="en" xml:lang="en">
266        <div class="titlepage">
267          <div>
268            <div>
269              <h3 class="title"><a id="dpl_cursor_range"></a>Key Ranges</h3>
270            </div>
271          </div>
272        </div>
273        <p>
274                        You can restrict the scope of a cursor's movement
275                        by specifying a <span class="emphasis"><em>range</em></span> when you
276                        create the cursor. The cursor can then never be
277                        positioned outside of the specified range.
278                </p>
279        <p>
280                        When specifying a range, you indicate whether a
281                        range bound is <span class="emphasis"><em>inclusive</em></span> or
282                        <span class="emphasis"><em>exclusive</em></span> by providing a
283                        boolean value for each range.
284                        <code class="literal">true</code> indicates that the provided
285                        bound is inclusive, while <code class="literal">false</code>
286                        indicates that it is exclusive.
287                </p>
288        <p>
289                        You provide this information when you call
290                        <code class="classname">PrimaryIndex.entities()</code>
291                        or
292                        <code class="classname">SecondaryIndex.entities()</code>.
293                        For example, suppose you had a class indexed by
294                        numerical information. Suppose further that you
295                        wanted to examine only those objects with indexed
296                        values of 100 - 199. Then (assuming the numerical
297                        information is the primary index), you can bound
298                        your cursor as follows:
299                </p>
300        <pre class="programlisting">
301EntityCursor&lt;SomeEntityClass&gt; cursor = 
302    primaryIndex.entities(100, true, 200, false);
303
304try {
305    for (SomeEntityClass sec : cursor {
306        // Do something here to objects ranged from 100 to 199
307    }
308// Always make sure the cursor is closed when we are done with it.
309} finally {
310    cursor.close(); } </pre>
311      </div>
312    </div>
313    <div class="navfooter">
314      <hr />
315      <table width="100%" summary="Navigation footer">
316        <tr>
317          <td width="40%" align="left"><a accesskey="p" href="simpleget.html">Prev</a>��</td>
318          <td width="20%" align="center">
319            <a accesskey="u" href="persist_access.html">Up</a>
320          </td>
321          <td width="40%" align="right">��<a accesskey="n" href="dpl_entityjoin.html">Next</a></td>
322        </tr>
323        <tr>
324          <td width="40%" align="left" valign="top">Retrieving Objects from an Entity Store��</td>
325          <td width="20%" align="center">
326            <a accesskey="h" href="index.html">Home</a>
327          </td>
328          <td width="40%" align="right" valign="top">��Join Cursors</td>
329        </tr>
330      </table>
331    </div>
332  </body>
333</html>
334