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<String,SimpleEntityClass> pi = 60 store.getPrimaryIndex(String.class, SimpleEntityClass.class); 61EntityCursor<SimpleEntityClass> pi_cursor = pi.entities(); 62try { 63 Iterator<SimpleEntityClass> 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<String,SimpleEntityClass> pi = 76 store.getPrimaryIndex(String.class, SimpleEntityClass.class); 77EntityCursor<SimpleEntityClass> 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<String,SimpleEntityClass> pi = 147 store.getPrimaryIndex(String.class, SimpleEntityClass.class); 148 149SecondaryIndex<String,String,SimpleEntityClass> si = 150 store.getSecondaryIndex(pi, String.class, "sKey"); 151 152EntityCursor<SimpleEntityClass> 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<String,SimpleEntityClass> pi = 231 store.getPrimaryIndex(String.class, SimpleEntityClass.class); 232 233SecondaryIndex<String,String,SimpleEntityClass> si = 234 store.getSecondaryIndex(pi, String.class, "sKey"); 235 236EntityCursor<SimpleEntityClass> sec_cursor = 237 si.subIndex("skeyone").entities(); 238 239try { 240 Iterator<SimpleEntityClass> 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<SomeEntityClass> 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