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