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>Database Joins</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="indexes.html" title="Chapter��10.��Secondary Databases" />
11    <link rel="previous" href="secondaryCursor.html" title="&#10;        Using Secondary Cursors&#10;        &#10;    " />
12    <link rel="next" href="javaindexusage.html" title="Secondary Database Example" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Database Joins</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="secondaryCursor.html">Prev</a>��</td>
22          <th width="60%" align="center">Chapter��10.��Secondary Databases</th>
23          <td width="20%" align="right">��<a accesskey="n" href="javaindexusage.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="joins"></a>Database Joins</h2>
33          </div>
34        </div>
35        <div></div>
36      </div>
37      <p>
38        If you have two or more secondary databases associated with a primary
39        database, then you can retrieve primary records based on the intersection of 
40        multiple secondary entries. You do this using a
41        <span><tt class="classname">JoinCursor</tt>.</span>
42        
43    </p>
44      <p>
45        Throughout this document we have presented a 
46            <span>class</span>
47            
48        that stores 
49            <span>inventory</span>
50        information on grocery
51            
52            
53        That 
54            <span>class</span>
55            
56        is fairly simple with a limited
57        number of data members, few of which would be interesting from a query
58        perspective. But suppose, instead, that we were storing 
59        information on something with many more characteristics that can be queried, such
60        as an automobile. In that case, you may be storing information such as
61        color, number of doors, fuel mileage, automobile type, number of
62        passengers, make, model, and year, to name just a few.
63    </p>
64      <p>
65        In this case, you would still likely be using some unique value to key your
66        primary entries (in the United States, the automobile's VIN would be
67        ideal for this purpose). You would then create a 
68            <span>class</span>
69            
70        that identifies
71        all the characteristics of the automobiles in your inventory. 
72        
73        <span>
74            You would
75            also have to create some mechanism by which you would move instances of
76            this class in and out of Java <tt class="literal">byte</tt> arrays. We
77            described the concepts and mechanisms by which you can perform these
78            activities in <a href="DBEntry.html">Database Records</a>.
79        </span>
80    </p>
81      <p>
82        To query this data, you might then create multiple secondary databases,
83        one for each of the characteristics that you want to query. For
84        example, you might create a secondary for color, another for number of
85        doors, another for number of passengers, and so forth. Of course, you
86        will need a unique 
87            <span>key creator</span>
88            
89        for each such secondary database. You do
90        all of this using the concepts and techniques described throughout this
91        chapter.
92    </p>
93      <p>
94        Once you have created this primary database and all interesting
95        secondaries, what you have is the ability to retrieve automobile records
96        based on a single characteristic. You can, for example, find all the
97        automobiles that are red. Or you can find all the automobiles that have
98        four doors. Or all the automobiles that are minivans. 
99    </p>
100      <p>
101        The next most natural step, then, is to form compound queries, or joins.
102        For example, you might want to find all the automobiles that are red,
103        and that were built by Toyota, and that are minivans. You can do this
104        using a 
105            <span><tt class="classname">JoinCursor</tt> class instance.</span>
106            
107    </p>
108      <div class="sect2" lang="en" xml:lang="en">
109        <div class="titlepage">
110          <div>
111            <div>
112              <h3 class="title"><a id="joinUsage"></a>Using Join Cursors</h3>
113            </div>
114          </div>
115          <div></div>
116        </div>
117        <p>
118            To use a join cursor:
119        </p>
120        <div class="itemizedlist">
121          <ul type="disc">
122            <li>
123              <p>
124                    Open two or more 
125                        <span>secondary cursors. These </span>
126                    cursors 
127                        
128                        <span>for</span> 
129                    secondary databases that are associated with
130                    the same primary database.
131                </p>
132            </li>
133            <li>
134              <p>
135                    Position each such cursor to the secondary key
136                    value in which you are interested. For example, to build on
137                    the previous description, the cursor for the color
138                    database is positioned to the <tt class="literal">red</tt> records
139                    while the cursor for the model database is positioned to the
140                    <tt class="literal">minivan</tt> records, and the cursor for the
141                    make database is positioned to <tt class="literal">Toyota</tt>.
142                </p>
143            </li>
144            <li>
145              <p>
146
147                    Create an array of <span>secondary</span> cursors, and
148                    place in it each of the cursors that are participating in your join query. 
149                    
150
151                </p>
152            </li>
153            <li>
154              <p>
155
156                    Obtain a join cursor. You do this using the 
157                        <tt class="methodname">Database.join()</tt> 
158                         
159                         
160                    method.  You must pass this method the array of secondary cursors that you
161                    opened and positioned in the previous steps.
162                </p>
163            </li>
164            <li>
165              <p>
166                    Iterate over the set of matching records
167                        <span>using <tt class="methodname">JoinCursor.getNext()</tt></span>
168                    until
169                    <span><tt class="classname">OperationStatus</tt> is not <tt class="literal">SUCCESS</tt>.</span>
170                    
171                </p>
172            </li>
173            <li>
174              <p>
175                    Close your <span>join</span> cursor.
176                </p>
177            </li>
178            <li>
179              <p>
180                    If you are done with them, close all your <span>secondary</span> cursors.
181                </p>
182            </li>
183          </ul>
184        </div>
185        <p>
186            For example:
187        </p>
188        <a id="java_index9"></a>
189        <pre class="programlisting">package db.GettingStarted;
190
191import com.sleepycat.db.Database;
192import com.sleepycat.db.DatabaseEntry;
193import com.sleepycat.db.DatabaseException;
194import com.sleepycat.db.JoinCursor;
195import com.sleepycat.db.LockMode;
196import com.sleepycat.db.OperationStatus;
197import com.sleepycat.db.SecondaryCursor;
198import com.sleepycat.db.SecondaryDatabase;
199
200...
201
202// Database and secondary database opens omitted for brevity.
203// Assume a primary database handle:
204//   automotiveDB
205// Assume 3 secondary database handles:
206//   automotiveColorDB  -- index based on automobile color
207//   automotiveTypeDB  -- index based on automobile type
208//   automotiveMakeDB   -- index based on the manufacturer
209Database automotiveDB = null;
210SecondaryDatabase automotiveColorDB = null;
211SecondaryDatabase automotiveTypeDB = null;
212SecondaryDatabase automotiveMakeDB = null;
213
214// Query strings:
215String theColor = "red";
216String theType = "minivan";
217String theMake = "Toyota";
218
219// Secondary cursors used for the query:
220SecondaryCursor colorSecCursor = null;
221SecondaryCursor typeSecCursor = null;
222SecondaryCursor makeSecCursor = null;
223
224// The join cursor
225JoinCursor joinCursor = null;
226
227// These are needed for our queries
228DatabaseEntry foundKey = new DatabaseEntry();
229DatabaseEntry foundData = new DatabaseEntry();
230
231// All cursor operations are enclosed in a try block to ensure that they
232// get closed in the event of an exception.
233
234try {
235    // Database entries used for the query:
236    DatabaseEntry color = new DatabaseEntry(theColor.getBytes("UTF-8"));
237    DatabaseEntry type = new DatabaseEntry(theType.getBytes("UTF-8"));
238    DatabaseEntry make = new DatabaseEntry(theMake.getBytes("UTF-8"));
239
240    colorSecCursor = automotiveColorDB.openSecondaryCursor(null, null); 
241    typeSecCursor = automotiveTypeDB.openSecondaryCursor(null, null); 
242    makeSecCursor = automotiveMakeDB.openSecondaryCursor(null, null); 
243
244    // Position all our secondary cursors to our query values.
245    OperationStatus colorRet = 
246        colorSecCursor.getSearchKey(color, foundData, LockMode.DEFAULT);
247    OperationStatus typeRet = 
248        typeSecCursor.getSearchKey(type, foundData, LockMode.DEFAULT);
249    OperationStatus makeRet = 
250        makeSecCursor.getSearchKey(make, foundData, LockMode.DEFAULT);
251
252    // If all our searches returned successfully, we can proceed
253    if (colorRet == OperationStatus.SUCCESS &amp;&amp;
254        typeRet == OperationStatus.SUCCESS &amp;&amp;
255        makeRet == OperationStatus.SUCCESS) {
256
257        // Get a secondary cursor array and populate it with our
258        // positioned cursors
259        SecondaryCursor[] cursorArray = {colorSecCursor,
260                                         typeSecCursor, 
261                                         makeSecCursor};
262
263        // Create the join cursor
264        joinCursor = automotiveDB.join(cursorArray, null);
265
266        // Now iterate over the results, handling each in turn
267        while (joinCursor.getNext(foundKey, foundData, LockMode.DEFAULT) ==
268                        OperationStatus.SUCCESS) {
269
270            // Do something with the key and data retrieved in
271            // foundKey and foundData
272        }
273    }
274} catch (DatabaseException dbe) {
275    // Error reporting goes here
276} catch (Exception e) {
277    // Error reporting goes here
278} finally {
279    try {
280        // Make sure to close out all our cursors
281        if (colorSecCursor != null) {
282            colorSecCursor.close();
283        }
284        if (typeSecCursor != null) {
285            typeSecCursor.close();
286        }
287        if (makeSecCursor != null) {
288            makeSecCursor.close();
289        }
290        if (joinCursor != null) {
291            joinCursor.close();
292        }
293    } catch (DatabaseException dbe) {
294        // Error reporting goes here
295    }
296} </pre>
297      </div>
298      <div class="sect2" lang="en" xml:lang="en">
299        <div class="titlepage">
300          <div>
301            <div>
302              <h3 class="title"><a id="joinconfig"></a>JoinCursor Properties</h3>
303            </div>
304          </div>
305          <div></div>
306        </div>
307        <p>
308            You can set <tt class="classname">JoinCursor</tt> properties using the
309            <tt class="classname">JoinConfig</tt> class. Currently there is just one property that you can
310            set:
311        </p>
312        <div class="itemizedlist">
313          <ul type="disc">
314            <li>
315              <p>
316                    <tt class="methodname">JoinConfig.setNoSort()</tt>
317                </p>
318              <p>
319                    Specifies whether automatic sorting of input cursors is disabled. The cursors are sorted from the
320					one that refers to the least number of data items to the one that refers to the most.
321                </p>
322              <p>
323					If the data is structured so that cursors with many data items also share many common elements,
324					higher performance will result from listing those cursors before cursors with fewer data
325					items. Turning off sorting permits applications to specify cursors in the proper order given this
326					scenario.
327				</p>
328              <p>
329					The default value is <tt class="literal">false</tt> (automatic cursor sorting is performed).
330				</p>
331              <p>
332                    For example:
333                </p>
334              <a id="je_index10"></a>
335              <pre class="programlisting">// All database and environments omitted
336JoinConfig config = new JoinConfig();
337config.setNoSort(true);
338JoinCursor joinCursor = myDb.join(cursorArray, config); </pre>
339            </li>
340          </ul>
341        </div>
342      </div>
343    </div>
344    <div class="navfooter">
345      <hr />
346      <table width="100%" summary="Navigation footer">
347        <tr>
348          <td width="40%" align="left"><a accesskey="p" href="secondaryCursor.html">Prev</a>��</td>
349          <td width="20%" align="center">
350            <a accesskey="u" href="indexes.html">Up</a>
351          </td>
352          <td width="40%" align="right">��<a accesskey="n" href="javaindexusage.html">Next</a></td>
353        </tr>
354        <tr>
355          <td width="40%" align="left" valign="top">
356        Using Secondary Cursors
357        
358    ��</td>
359          <td width="20%" align="center">
360            <a accesskey="h" href="index.html">Home</a>
361          </td>
362          <td width="40%" align="right" valign="top">��Secondary Database Example</td>
363        </tr>
364      </table>
365    </div>
366  </body>
367</html>
368