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