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>Implementing Key 7 Creators 8 9 </title> 10 <link rel="stylesheet" href="gettingStarted.css" type="text/css" /> 11 <meta name="generator" content="DocBook XSL Stylesheets V1.62.4" /> 12 <link rel="home" href="index.html" title="Getting Started with Berkeley DB" /> 13 <link rel="up" href="indexes.html" title="Chapter��10.��Secondary Databases" /> 14 <link rel="previous" href="indexes.html" title="Chapter��10.��Secondary Databases" /> 15 <link rel="next" href="secondaryProps.html" title="Secondary Database Properties" /> 16 </head> 17 <body> 18 <div class="navheader"> 19 <table width="100%" summary="Navigation header"> 20 <tr> 21 <th colspan="3" align="center">Implementing Key 22 Creators 23 24 </th> 25 </tr> 26 <tr> 27 <td width="20%" align="left"><a accesskey="p" href="indexes.html">Prev</a>��</td> 28 <th width="60%" align="center">Chapter��10.��Secondary Databases</th> 29 <td width="20%" align="right">��<a accesskey="n" href="secondaryProps.html">Next</a></td> 30 </tr> 31 </table> 32 <hr /> 33 </div> 34 <div class="sect1" lang="en" xml:lang="en"> 35 <div class="titlepage"> 36 <div> 37 <div> 38 <h2 class="title" style="clear: both"><a id="keyCreator"></a>Implementing Key 39 <span>Creators</span> 40 41 </h2> 42 </div> 43 </div> 44 <div></div> 45 </div> 46 <p> 47 You must provide every secondary database with a 48 <span>class</span> 49 50 that creates keys from primary records. You identify this 51 <span>class</span> 52 53 54 <span> 55 using the <tt class="methodname">SecondaryConfig.setKeyCreator()</tt> 56 method. 57 </span> 58 59 </p> 60 <p> 61 You can create keys using whatever data you want. Typically you will 62 base your key on some information found in a record's data, but you 63 can also use information found in the primary record's key. How you build 64 your keys is entirely dependent upon the nature of the index that you 65 want to maintain. 66 </p> 67 <p> 68 You implement a key creator by writing a class that implements the 69 <tt class="classname">SecondaryKeyCreator</tt> interface. This interface 70 requires you to implement the <tt class="methodname">SecondaryKeyCreator.createSecondaryKey()</tt> 71 method. 72 </p> 73 <p> 74 One thing to remember when implementing this method is that you will 75 need a way to extract the necessary information from the data's 76 <tt class="classname">DatabaseEntry</tt> and/or the key's 77 <tt class="classname">DatabaseEntry</tt> that are provided on calls to this 78 method. If you are using complex objects, then you are probably using the 79 Bind APIs to perform this conversion. The easiest thing to do is to 80 instantiate the <tt class="classname">EntryBinding</tt> or 81 <tt class="classname">TupleBinding</tt> that you need to perform the 82 conversion, and then provide this to your key creator's constructor. 83 The Bind APIs are introduced in <a href="bindAPI.html">Using the BIND APIs</a>. 84 </p> 85 <p> 86 <tt class="methodname">SecondaryKeyCreator.createSecondaryKey()</tt> returns a 87 boolean. A return value of <tt class="literal">false</tt> indicates that 88 no secondary key exists, and therefore no record should be added to the secondary database for that primary record. 89 If a record already exists in the secondary database, it is deleted. 90 </p> 91 <p> 92 For example, suppose your primary database uses the following class 93 for its record data: 94 </p> 95 <a id="java_index3"></a> 96 <pre class="programlisting">package db.GettingStarted; 97 98public class PersonData { 99 private String userID; 100 private String surname; 101 private String familiarName; 102 103 public PersonData(String userID, String surname, String familiarName) { 104 this.userID = userID; 105 this.surname = surname; 106 this.familiarName = familiarName; 107 } 108 109 public String getUserID() { 110 return userID; 111 } 112 113 public String getSurname() { 114 return surname; 115 } 116 117 public String getFamiliarName() { 118 return familiarName; 119 } 120} </pre> 121 <p> 122 Also, suppose that you have created a custom tuple binding, 123 <tt class="classname">PersonDataBinding</tt>, that you use to convert 124 <tt class="classname">PersonData</tt> objects to and from 125 <tt class="classname">DatabaseEntry</tt> objects. (Custom tuple bindings are 126 described in <a href="bindAPI.html#customTuple">Custom Tuple Bindings</a>.) 127 </p> 128 <p> 129 Finally, suppose you want a secondary database that is keyed based 130 on the person's full name. 131 </p> 132 <p> 133 Then in this case you might create a key creator as follows: 134 </p> 135 <a id="java_index4"></a> 136 <pre class="programlisting">package db.GettingStarted; 137 138import com.sleepycat.bind.tuple.TupleBinding; 139import com.sleepycat.db.SecondaryKeyCreator; 140import com.sleepycat.db.DatabaseEntry; 141import com.sleepycat.db.DatabaseException; 142import com.sleepycat.db.SecondaryDatabase; 143 144import java.io.IOException; 145 146public class FullNameKeyCreator implements SecondaryKeyCreator { 147 148 private TupleBinding theBinding; 149 150 public FullNameKeyCreator(TupleBinding theBinding1) { 151 theBinding = theBinding1; 152 } 153 154 public boolean createSecondaryKey(SecondaryDatabase secDb, 155 DatabaseEntry keyEntry, 156 DatabaseEntry dataEntry, 157 DatabaseEntry resultEntry) { 158 159 try { 160 PersonData pd = 161 (PersonData) theBinding.entryToObject(dataEntry); 162 String fullName = pd.getFamiliarName() + " " + 163 pd.getSurname(); 164 resultEntry.setData(fullName.getBytes("UTF-8")); 165 } catch (IOException willNeverOccur) {} 166 return true; 167 } 168} </pre> 169 <p>Finally, you use this key creator as follows:</p> 170 <a id="java_index5"></a> 171 <pre class="programlisting">package db.GettingStarted; 172 173import com.sleepycat.bind.tuple.TupleBinding; 174 175import com.sleepycat.db.Database; 176import com.sleepycat.db.DatabaseException; 177import com.sleepycat.db.DatabaseType; 178import com.sleepycat.db.SecondaryDatabase; 179import com.sleepycat.db.SecondaryConfig; 180 181import java.io.FileNotFoundException; 182 183... 184Database myDb = null; 185SecondaryDatabase mySecDb = null; 186try { 187 // Primary database open omitted for brevity 188... 189 190 TupleBinding myDataBinding = new MyTupleBinding(); 191 FullNameKeyCreator fnkc = new FullNameKeyCreator(myDataBinding); 192 193 SecondaryConfig mySecConfig = new SecondaryConfig(); 194 mySecConfig.setKeyCreator(fnkc); 195 mySecConfig.setType(DatabaseType.BTREE); 196 197 //Perform the actual open 198 String secDbName = "mySecondaryDatabase"; 199 mySecDb = new SecondaryDatabase(secDbName, null, myDb, mySecConfig); 200} catch (DatabaseException de) { 201 // Exception handling goes here 202} catch (FileNotFoundException fnfe) { 203 // Exception handling goes here 204} finally { 205 try { 206 if (mySecDb != null) { 207 mySecDb.close(); 208 } 209 210 if (myDb != null) { 211 myDb.close(); 212 } 213 } catch (DatabaseException dbe) { 214 // Exception handling goes here 215 } 216}</pre> 217 <div class="sect2" lang="en" xml:lang="en"> 218 <div class="titlepage"> 219 <div> 220 <div> 221 <h3 class="title"><a id="multikeys"></a>Working with Multiple Keys</h3> 222 </div> 223 </div> 224 <div></div> 225 </div> 226 <p> 227 Until now we have only discussed indexes as if there is 228 a one-to-one relationship between the secondary key and 229 the primary database record. In fact, it is possible to 230 generate multiple keys for any given record, provided 231 that you take appropriate steps in your key creator 232 to do so. 233 </p> 234 <p> 235 For example, suppose you had a database that contained 236 information about books. Suppose further that you 237 sometimes want to look up books by author. Because 238 sometimes books have multiple authors, you may want to 239 return multiple secondary keys for every book that you 240 index. 241 </p> 242 <p> 243 To do this, you write a key creator that implements 244 <tt class="classname">SecondaryMultiKeyCreator</tt> 245 instead of 246 <tt class="classname">SecondaryKeyCreator</tt>. The key 247 difference between the two is that 248 <tt class="classname">SecondaryKeyCreator</tt> 249 uses a single <tt class="classname">DatabaseEntry</tt> 250 object as the result, while 251 <tt class="classname">SecondaryMultiKeyCreator</tt> 252 returns a set of <tt class="classname">DatabaseEntry</tt> 253 objects (using <tt class="classname">java.util.Set</tt>). 254 Also, you assign the 255 <tt class="classname">SecondaryMultiKeyCreator</tt> 256 implementation using 257 <tt class="methodname">SecondaryConfig.setMultiKeyCreator()</tt> 258 instead of 259 <tt class="methodname">SecondaryConfig.setKeyCreator()</tt>. 260 </p> 261 <p> 262 For example: 263 </p> 264 <pre class="programlisting">package db.GettingStarted; 265 266import com.sleepycat.db.DatabaseEntry; 267import com.sleepycat.db.DatabaseException; 268import com.sleepycat.db.SecondaryDatabase; 269import com.sleepycat.db.SecondaryMultiKeyCreator; 270 271import java.util.HashSet; 272import java.util.Set; 273 274public class MyMultiKeyCreator implements SecondaryMultiKeyCreator { 275 276 // Constructor not implemented. How this is implemented depends on 277 // how you want to extract the data for your keys. 278 MyMultiKeyCreator() { 279 ... 280 } 281 282 // Abstract method that we must implement 283 public void createSecondaryKeys(SecondaryDatabase secDb, 284 DatabaseEntry keyEntry, // From the primary 285 DatabaseEntry dataEntry, // From the primary 286 Set results) // Results set 287 throws DatabaseException { 288 289 try { 290 // Create your keys, adding each to the set 291 292 // Creation of key 'a' not shown 293 results.add(a) 294 295 // Creation of key 'b' not shown 296 results.add(b) 297 298 } catch (IOException willNeverOccur) {} 299 } 300} </pre> 301 </div> 302 </div> 303 <div class="navfooter"> 304 <hr /> 305 <table width="100%" summary="Navigation footer"> 306 <tr> 307 <td width="40%" align="left"><a accesskey="p" href="indexes.html">Prev</a>��</td> 308 <td width="20%" align="center"> 309 <a accesskey="u" href="indexes.html">Up</a> 310 </td> 311 <td width="40%" align="right">��<a accesskey="n" href="secondaryProps.html">Next</a></td> 312 </tr> 313 <tr> 314 <td width="40%" align="left" valign="top">Chapter��10.��Secondary Databases��</td> 315 <td width="20%" align="center"> 316 <a accesskey="h" href="index.html">Home</a> 317 </td> 318 <td width="40%" align="right" valign="top">��Secondary Database Properties</td> 319 </tr> 320 </table> 321 </div> 322 </body> 323</html> 324