Import BSDDB 4.7.25 (as of svn r89086)

This commit is contained in:
Zachary Ware
2017-09-04 13:40:25 -05:00
parent 4b29e0458f
commit 8f590873d0
4781 changed files with 2241032 additions and 6 deletions

Binary file not shown.

View File

@@ -0,0 +1,170 @@
<?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>Managing Databases in Environments</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DB.html" title="Chapter 7. Databases" />
<link rel="previous" href="dbErrorReporting.html" title="Error Reporting Functions" />
<link rel="next" href="CoreJavaUsage.html" title="Database Example" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Managing Databases in Environments</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dbErrorReporting.html">Prev</a> </td>
<th width="60%" align="center">Chapter 7. Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="CoreJavaUsage.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="CoreEnvUsage"></a>Managing Databases in Environments</h2>
</div>
</div>
<div></div>
</div>
<p>
In
<span>
<a href="Env.html">Database Environments</a>,
</span>
we introduced
environments. While environments are not used in the example built in this book,
they are so commonly used for a wide class of DB applications that it is
necessary to show their basic usage, if only from a completeness perspective.
</p>
<p>
To use an environment, you must first
open it. At open time, you must identify the directory in
which it resides. This directory must exist prior to the open attempt.
You can also identify open properties, such as whether the environment can be
created if it does not already exist.
</p>
<p>
You will also need to initialize the in-memory cache when you open your environment.
</p>
<p>
For example, to
<span>create an environment handle and</span>
open an environment:
</p>
<a id="java_env1"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import java.io.File;
import java.io.FileNotFoundException;
...
Environment myEnv = null;
File envHome = new File("/export1/testEnv");
try {
EnvironmentConfig envConf = new EnvironmentConfig();
envConf.setAllowCreate(true); // If the environment does not
// exist, create it.
envConf.setInitializeCache(true); // Initialize the in-memory
// cache.
myEnv = new Environment(envHome, envConf);
} catch (DatabaseException de) {
// Exception handling goes here
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
} </pre>
<p>
Once an environment is opened, you can open databases in it. Note that by default databases
are stored in the environment's home directory, or relative to that directory if you
provide any sort of a path in the database's file name:
</p>
<a id="java_env2"></a>
<pre class="programlisting">package db.GettingStarted;
<b class="userinput"><tt>import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseType;</tt></b>
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import java.io.File;
import java.io.FileNotFoundException;
...
Environment myEnv = null;
Database myDb = null;
File envHome = new File("/export1/testEnv");
String dbFileName = new String("mydb.db", "UTF-8");
try {
EnvironmentConfig envConf = new EnvironmentConfig();
envConf.setAllowCreate(true);
DatabaseConfig dbConfig = new DatabaseConfig();
<b class="userinput"><tt>dbConfig.setAllowCreate(true);
dbConfig.setType(DatabaseType.BTREE);</tt></b>
myEnv = new Environment(envHome, envConf);
<b class="userinput"><tt>myDb = myEnv.openDatabase(null, dbFileName, null, dbConfig);</tt></b>
} catch (DatabaseException de) {
// Exception handling goes here
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
} </pre>
<p>
When you are done with an environment, you must close it. Before you close an environment,
make sure you close any opened databases.
</p>
<a id="java_env3"></a>
<pre class="programlisting">finally {
try {
if (myDb != null) {
myDb.close();
}
if (myEnv != null) {
myEnv.close();
}
} catch (DatabaseException de) {
// Exception handling goes here
}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dbErrorReporting.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DB.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="CoreJavaUsage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Error Reporting Functions </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Database Example</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,183 @@
<?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>Database Example</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DB.html" title="Chapter 7. Databases" />
<link rel="previous" href="CoreEnvUsage.html" title="Managing Databases in Environments" />
<link rel="next" href="DBEntry.html" title="Chapter 8. Database Records" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Database Example</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="CoreEnvUsage.html">Prev</a> </td>
<th width="60%" align="center">Chapter 7. Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="DBEntry.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="CoreJavaUsage"></a>Database Example</h2>
</div>
</div>
<div></div>
</div>
<p>
Throughout this book we will build a couple of applications that load
and retrieve inventory data from DB databases. While we are not yet ready to
begin reading from or writing to our databases, we can at least create
the class that we will use to manage our databases.
</p>
<p>
Note that subsequent examples in this book will build on this code to
perform the more interesting work of writing to and reading from the
databases.
</p>
<p>
Note that you can find the complete implementation of these functions
in:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
<div class="example">
<a id="MyDb"></a>
<p class="title">
<b>Example 7.1 MyDbs Class</b>
</p>
<p>
To manage our database open and close activities, we encapsulate them
in the <tt class="classname">MyDbs</tt> class. There are several good reasons
to do this, the most important being that we can ensure our databases are
closed by putting that activity in the <tt class="classname">MyDbs</tt>
class destructor.
</p>
<p>
To begin, we import some needed classes:
</p>
<a id="java_db12"></a>
<pre class="programlisting">// File: MyDbs.java
package db.GettingStarted;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
import java.io.FileNotFoundException; </pre>
<p>
And then we write our class declaration and provided some necessary private data members:
</p>
<a id="java_db13"></a>
<pre class="programlisting">public class MyDbs {
// The databases that our application uses
private Database vendorDb = null;
private Database inventoryDb = null;
private String vendordb = "VendorDB.db";
private String inventorydb = "InventoryDB.db";
// Our constructor does nothing
public MyDbs() {} </pre>
<p>
Next we need a <tt class="methodname">setup()</tt> method. This is where
we configure and open our databases.
</p>
<a id="java_db14"></a>
<pre class="programlisting"> // The setup() method opens all our databases
// for us.
public void setup(String databasesHome)
throws DatabaseException {
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setErrorStream(System.err);
myDbConfig.setErrorPrefix("MyDbs");
myDbConfig.setType(DatabaseType.BTREE);
myDbConfig.setAllowCreate(true);
// Now open, or create and open, our databases
// Open the vendors and inventory databases
try {
vendordb = databasesHome + "/" + vendordb;
vendorDb = new Database(vendordb,
null,
myDbConfig);
inventorydb = databasesHome + "/" + inventorydb;
inventoryDb = new Database(inventorydb,
null,
myDbConfig);
} catch(FileNotFoundException fnfe) {
System.err.println("MyDbs: " + fnfe.toString());
System.exit(-1);
}
} </pre>
<p>
Finally, we provide some getter methods, and our <tt class="methodname">close()</tt> method.
</p>
<a id="java_db15"></a>
<pre class="programlisting"> // getter methods
public Database getVendorDB() {
return vendorDb;
}
public Database getInventoryDB() {
return inventoryDb;
}
// Close the databases
public void close() {
try {
if (vendorDb != null) {
vendorDb.close();
}
if (inventoryDb != null) {
inventoryDb.close();
}
} catch(DatabaseException dbe) {
System.err.println("Error closing MyDbs: " +
dbe.toString());
System.exit(-1);
}
}
} </pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="CoreEnvUsage.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DB.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="DBEntry.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Managing Databases in Environments </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 8. Database Records</td>
</tr>
</table>
</div>
</body>
</html>

201
docs/gsg/JAVA/Cursors.html Normal file
View File

@@ -0,0 +1,201 @@
<?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>Chapter 9. Using Cursors</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="baseapi.html" title="Part II. Programming with the Base API" />
<link rel="previous" href="dbtJavaUsage.html" title="Database Usage Example" />
<link rel="next" href="Positioning.html" title="Getting Records Using the Cursor" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 9. Using Cursors</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dbtJavaUsage.html">Prev</a> </td>
<th width="60%" align="center">Part II. Programming with the Base API</th>
<td width="20%" align="right"> <a accesskey="n" href="Positioning.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="Cursors"></a>Chapter 9. Using Cursors</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="Cursors.html#openCursor">Opening and Closing Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="Positioning.html">Getting Records Using the Cursor</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="Positioning.html#cursorsearch">Searching for Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="Positioning.html#getdups">Working with Duplicate Records</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="PutEntryWCursor.html">Putting Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DeleteEntryWCursor.html">Deleting Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="ReplacingEntryWCursor.html">Replacing Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="cursorJavaUsage.html">Cursor Example</a>
</span>
</dt>
</dl>
</div>
<p>
Cursors provide a mechanism by which you can iterate over the records in a
database. Using cursors, you can get, put, and delete database records. If
a database allows duplicate records, then cursors are
<span>the easiest way that you can access anything
other than the first record for a given key.</span>
</p>
<p>
This chapter introduces cursors. It explains how to open and close them, how
to use them to modify databases, and how to use them with duplicate records.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="openCursor"></a>Opening and Closing Cursors</h2>
</div>
</div>
<div></div>
</div>
<p>
To use a cursor, you must open it using the <tt class="methodname">Database.openCursor()</tt>
method. When you open a
cursor, you can optionally pass it a <tt class="classname">CursorConfig</tt>
object to set cursor properties.
<span>
The cursor properties that you can set allows you to
control the isolation level that the cursor will obey. See
the
<i class="citetitle">Berkeley DB Getting Started with Transaction Processing</i> guide for more
information.
</span>
</p>
<p>For example:</p>
<a id="java_cursor1"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseException;
import java.io.FileNotFoundException;
...
Database myDatabase = null;
Cursor myCursor = null;
try {
myDatabase = new Database("myDB", null, null);
myCursor = myDatabase.openCursor(null, null);
} catch (FileNotFoundException fnfe) {
// Exception handling goes here ...
} catch (DatabaseException dbe) {
// Exception handling goes here ...
}</pre>
<p>
To close the cursor, call the <tt class="methodname">Cursor.close()</tt>
method. Note that if you close a database that has cursors open in it,
then it will throw an exception and close any open cursors for you.
For best results, close your cursors from within a
<tt class="literal">finally</tt> block.
</p>
<a id="java_cursor2"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
...
try {
...
} catch ... {
} finally {
try {
if (myCursor != null) {
myCursor.close();
}
if (myDatabase != null) {
myDatabase.close();
}
} catch(DatabaseException dbe) {
System.err.println("Error in close: " + dbe.toString());
}
} </pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dbtJavaUsage.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="baseapi.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="Positioning.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Database Usage Example </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Getting Records Using the Cursor</td>
</tr>
</table>
</div>
</body>
</html>

181
docs/gsg/JAVA/DB.html Normal file
View File

@@ -0,0 +1,181 @@
<?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>Chapter 7. Databases</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="baseapi.html" title="Part II. Programming with the Base API" />
<link rel="previous" href="baseapi.html" title="Part II. Programming with the Base API" />
<link rel="next" href="coredbclose.html" title="Closing Databases" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 7. Databases</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="baseapi.html">Prev</a> </td>
<th width="60%" align="center">Part II. Programming with the Base API</th>
<td width="20%" align="right"> <a accesskey="n" href="coredbclose.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="DB"></a>Chapter 7. Databases</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="DB.html#DBOpen">Opening Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="coredbclose.html">Closing Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DBConfig.html">Database Properties</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DBAdmin.html">Administrative Methods</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dbErrorReporting.html">Error Reporting Functions</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="CoreEnvUsage.html">Managing Databases in Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="CoreJavaUsage.html">Database Example</a>
</span>
</dt>
</dl>
</div>
<p>In Berkeley DB, a database is a collection of <span class="emphasis"><em>records</em></span>. Records,
in turn, consist of key/data pairings.
</p>
<p>
Conceptually, you can think of a
<tt class="classname">Database</tt>
as containing a two-column table where column 1 contains a key and column 2
contains data. Both the key and the data are managed using
<tt class="classname">DatabaseEntry</tt>
<span>class instances</span>
(see <a href="DBEntry.html">Database Records</a> for details on this
<span>class</span>
).
So, fundamentally, using a DB
<tt class="classname">Database</tt>
involves putting, getting, and deleting database records, which in turns involves efficiently
managing information
<span>encapsulated by </span>
<tt class="classname">DatabaseEntry</tt>
<span>objects.</span>
The next several chapters of this book are dedicated to those activities.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="DBOpen"></a>Opening Databases</h2>
</div>
</div>
<div></div>
</div>
<p>
You open a database by instantiating a <tt class="classname">Database</tt>
object.
</p>
<p>
Note that by default, DB does not create databases if they do not already exist.
To override this behavior, set the <a href="DBConfig.html" title="Database Properties">creation property</a> to true.
</p>
<p>
The following code fragment illustrates a database open:
</p>
<a id="java_db1"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import java.io.FileNotFoundException;
...
Database myDatabase = null;
...
try {
// Open the database. Create it if it does not already exist.
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
myDatabase = new Database ("sampleDatabase.db",
null,
dbConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
}</pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="baseapi.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="baseapi.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="coredbclose.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Part II. Programming with the Base API </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Closing Databases</td>
</tr>
</table>
</div>
</body>
</html>

124
docs/gsg/JAVA/DBAdmin.html Normal file
View File

@@ -0,0 +1,124 @@
<?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>Administrative Methods</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DB.html" title="Chapter 7. Databases" />
<link rel="previous" href="DBConfig.html" title="Database Properties" />
<link rel="next" href="dbErrorReporting.html" title="Error Reporting Functions" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Administrative Methods</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="DBConfig.html">Prev</a> </td>
<th width="60%" align="center">Chapter 7. Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="dbErrorReporting.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="DBAdmin"></a>Administrative Methods</h2>
</div>
</div>
<div></div>
</div>
<p>
Both the <tt class="classname">Environment</tt> and
<tt class="classname">Database</tt> classes provide methods that are useful
for manipulating databases. These methods are:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">Database.getDatabaseName()</tt>
</p>
<p>Returns the database's name.</p>
<a id="je_db3.1"></a>
<pre class="programlisting">String dbName = myDatabase.getDatabaseName();</pre>
</li>
<li>
<p>
<tt class="methodname">Database.rename()</tt>
</p>
<p>
Renames the specified database. If no value is given for the
<i class="parameter"><tt>database</tt></i> parameter, then the entire file
referenced by this method is renamed.
</p>
<p>
Never rename a database that has handles opened for it. Never rename a file that
contains databases with opened handles.
</p>
<a id="java_db9"></a>
<pre class="programlisting">import java.io.FileNotFoundException;
...
myDatabase.close();
try {
myDatabase.rename("mydb.db", // Database file to rename
null, // Database to rename. Not used so
// the entire file is renamed.
"newdb.db", // New name to use.
null); // DatabaseConfig object.
// None provided.
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
}</pre>
</li>
<li>
<p>
<tt class="methodname">Environment.truncateDatabase()</tt>
</p>
<p>
Deletes every record in the database and optionally returns the
number of records that were deleted. Note that it is much less
expensive to truncate a database without counting the number of
records deleted than it is to truncate and count.
</p>
<a id="je_db5"></a>
<pre class="programlisting">int numDiscarded =
myEnv.truncate(null, // txn handle
myDatabase.getDatabaseName(), // database name
true); // If true, then the
// number of records
// deleted are counted.
System.out.println("Discarded " + numDiscarded +
" records from database " +
myDatabase.getDatabaseName()); </pre>
</li>
</ul>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="DBConfig.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DB.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dbErrorReporting.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Database Properties </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Error Reporting Functions</td>
</tr>
</table>
</div>
</body>
</html>

256
docs/gsg/JAVA/DBEntry.html Normal file
View File

@@ -0,0 +1,256 @@
<?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>Chapter 8. Database Records</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="baseapi.html" title="Part II. Programming with the Base API" />
<link rel="previous" href="CoreJavaUsage.html" title="Database Example" />
<link rel="next" href="usingDbt.html" title="Reading and Writing Database Records" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 8. Database Records</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="CoreJavaUsage.html">Prev</a> </td>
<th width="60%" align="center">Part II. Programming with the Base API</th>
<td width="20%" align="right"> <a accesskey="n" href="usingDbt.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="DBEntry"></a>Chapter 8. Database Records</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="DBEntry.html#usingDbEntry">Using Database Records</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="usingDbt.html">Reading and Writing Database Records</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="usingDbt.html#databaseWrite">Writing Records to the Database</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#databaseRead">Getting Records from the Database</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#recordDelete">Deleting Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#datapersist">Data Persistence</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="bindAPI.html">Using the BIND APIs</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="bindAPI.html#bindPrimitive">Numerical and String Objects</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="bindAPI.html#object2dbt">Serializable Complex Objects</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="bindAPI.html#customTuple">Custom Tuple Bindings</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dbtJavaUsage.html">Database Usage Example</a>
</span>
</dt>
</dl>
</div>
<p>
DB records contain two parts — a key and some data. Both the key
and its corresponding data are
encapsulated in
<span><tt class="classname">DatabaseEntry</tt> class objects.</span>
Therefore, to access a DB record, you need two such
<span>objects,</span> one for the key and
one for the data.
</p>
<p>
<tt class="classname">DatabaseEntry</tt> can hold any kind of data from simple
Java primitive types to complex Java objects so long as that data can be
represented as a Java <tt class="literal">byte</tt> array. Note that due to
performance considerations, you should not use Java serialization to convert
a Java object to a <tt class="literal">byte</tt> array. Instead, use the Bind APIs
to perform this conversion (see
<a href="bindAPI.html">Using the BIND APIs</a> for more
information).
</p>
<p>
This chapter describes how you can convert both Java primitives and Java
class objects into and out of <tt class="literal">byte</tt> arrays. It also
introduces storing and retrieving key/value pairs from a database. In
addition, this chapter describes how you can use comparators to influence
how DB sorts its database records.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="usingDbEntry"></a>Using Database Records</h2>
</div>
</div>
<div></div>
</div>
<p>
Each database record is comprised of two
<span><tt class="classname">DatabaseEntry</tt> objects</span>
— one for the key and another for the data.
<span>The key and data information are passed to-
and returned from DB using
<tt class="classname">DatabaseEntry</tt> objects as <tt class="literal">byte</tt>
arrays. Using <tt class="classname">DatabaseEntry</tt>s allows DB to
change the underlying byte array as well as return multiple values (that
is, key and data). Therefore, using <tt class="classname">DatabaseEntry</tt> instances
is mostly an exercise in efficiently moving your keys and your data in
and out of <tt class="literal">byte</tt> arrays.</span>
</p>
<p>
For example, to store a database record where both the key and the
data are Java <tt class="classname">String</tt> objects, you instantiate a
pair of <tt class="classname">DatabaseEntry</tt> objects:
</p>
<a id="java_dbt1"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
...
String aKey = "key";
String aData = "data";
try {
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
} catch (Exception e) {
// Exception handling goes here
}
// Storing the record is described later in this chapter </pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
Notice that we specify <tt class="literal">UTF-8</tt> when we retrieve the
<tt class="literal">byte</tt> array from our <tt class="classname">String</tt>
object. Without parameters, <tt class="methodname">String.getBytes()</tt> uses the
Java system's default encoding. You should never use a system's default
encoding when storing data in a database because the encoding can change.
</p>
</div>
<p>
When the record is retrieved from the database, the method that you
use to perform this operation populates two <tt class="classname">DatabaseEntry</tt>
instances for you, one for the key and another for the data. Assuming Java
<tt class="classname">String</tt> objects, you retrieve your data from the
<tt class="classname">DatabaseEntry</tt> as follows:
</p>
<a id="java_dbt2"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
...
// theKey and theData are DatabaseEntry objects. Database
// retrieval is described later in this chapter. For now,
// we assume some database get method has populated these
// objects for us.
// Use DatabaseEntry.getData() to retrieve the encapsulated Java
// byte array.
byte[] myKey = theKey.getData();
byte[] myData = theData.getData();
String key = new String(myKey, "UTF-8");
String data = new String(myData, "UTF-8"); </pre>
<p>
There are a large number of mechanisms that you can use to move data in
and out of <tt class="literal">byte</tt> arrays. To help you with this
activity, DB provides the bind APIs. These APIs allow you to
efficiently store both primitive data types and complex objects in
<tt class="literal">byte</tt> arrays.
</p>
<p>
The next section describes basic database put and get operations. A
basic understanding of database access is useful when describing database
storage of more complex data such as is supported by the bind APIs. Basic
bind API usage is then described in <a href="bindAPI.html">Using the BIND APIs</a>.
</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="CoreJavaUsage.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="baseapi.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="usingDbt.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Database Example </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Reading and Writing Database Records</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,112 @@
<?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>Deleting Records Using Cursors</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Cursors.html" title="Chapter 9. Using Cursors" />
<link rel="previous" href="PutEntryWCursor.html" title="Putting Records Using Cursors" />
<link rel="next" href="ReplacingEntryWCursor.html" title="Replacing Records Using Cursors" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Deleting Records Using Cursors</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="PutEntryWCursor.html">Prev</a> </td>
<th width="60%" align="center">Chapter 9. Using Cursors</th>
<td width="20%" align="right"> <a accesskey="n" href="ReplacingEntryWCursor.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="DeleteEntryWCursor"></a>Deleting Records Using Cursors</h2>
</div>
</div>
<div></div>
</div>
<p>
To delete a record using a cursor, simply position the cursor to the
record that you want to delete and then call
</p>
<p>For example:</p>
<a id="java_cursor8"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Cursor cursor = null;
Database myDatabase = null;
try {
...
// Database open omitted for brevity
...
// Create DatabaseEntry objects
// searchKey is some String.
DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
// Open a cursor using a database handle
cursor = myDatabase.openCursor(null, null);
// Position the cursor. Ignoring the return value for clarity
OperationStatus retVal = cursor.getSearchKey(theKey, theData,
LockMode.DEFAULT);
// Count the number of records using the given key. If there is only
// one, delete that record.
if (cursor.count() == 1) {
System.out.println("Deleting " +
new String(theKey.getData(), "UTF-8") +
"|" +
new String(theData.getData(), "UTF-8"));
cursor.delete();
}
} catch (Exception e) {
// Exception handling goes here
} finally {
// Make sure to close the cursor
cursor.close();
}</pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="PutEntryWCursor.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Cursors.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="ReplacingEntryWCursor.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Putting Records Using Cursors </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Replacing Records Using Cursors</td>
</tr>
</table>
</div>
</body>
</html>

180
docs/gsg/JAVA/Env.html Normal file
View File

@@ -0,0 +1,180 @@
<?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>Chapter 2. Database Environments</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="previous" href="gettingit.html" title="Getting and Using DB " />
<link rel="next" href="EnvClose.html" title="Closing Database Environments" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 2. Database Environments</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="gettingit.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="EnvClose.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="Env"></a>Chapter 2. Database Environments</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="Env.html#EnvOpen">Opening Database Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="EnvClose.html">Closing Database Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="EnvProps.html">Environment Properties</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="EnvProps.html#envconfig">The EnvironmentConfig Class</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="EnvProps.html#envhandleconfig">EnvironmentMutableConfig</a>
</span>
</dt>
</dl>
</dd>
</dl>
</div>
<p>
Environments are optional, but very commonly used, for Berkeley DB
applications built using the base API. If you are using the DPL, then
environments are required.
</p>
<p>
Database environments encapsulate one or more databases. This encapsulation
provides your threads with efficient access to your databases by allowing a single
in-memory cache to be used for each of the databases contained in the
environment. This encapsulation also allows you to group operations performed against
multiple databases inside a single
transactions (see the <i class="citetitle">Berkeley DB Java Edition Getting Started with Transaction Processing</i> guide for more information).
</p>
<p>
Most commonly you use database environments to create and open
databases (you close individual databases using the individual
database handles). You can also use environments to delete and rename
databases. For transactional applications, you use the environment to start
transactions. For non-transactional
applications, you use the environment to sync your in-memory cache to disk.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="EnvOpen"></a>Opening Database Environments</h2>
</div>
</div>
<div></div>
</div>
<p>You open a database environment by instantiating an
<tt class="classname">Environment</tt> object. You must provide to the
constructor the name of the on-disk directory where the environment is to reside.
This directory location must exist or the open will fail.</p>
<p>By default, the environment is not created for you if it does not exist. Set the
<a href="EnvProps.html" title="Environment Properties">creation property</a> to <tt class="literal">true</tt> if
you want the environment to be created. For example:</p>
<a id="je_env1"></a>
<pre class="programlisting">
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.File;
...
// Open the environment. Allow it to be created if it does not already exist.
Environment myDbEnvironment = null;
try {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} </pre>
<pre class="programlisting">package db.gettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import java.io.File;
import java.io.FileNotFoundException;
...
// Open the environment. Allow it to be created if it does not already exist.
Environment myDbEnvironment = null;
try {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
} </pre>
<p>Your application can open and use as many environments as you have
disk and memory to manage, although most applications will use just one
environment. Also, you can instantiate multiple <tt class="classname">Environment</tt>
objects for the same physical environment.</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="gettingit.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="index.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="EnvClose.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Getting and Using DB  </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Closing Database Environments</td>
</tr>
</table>
</div>
</body>
</html>

101
docs/gsg/JAVA/EnvClose.html Normal file
View File

@@ -0,0 +1,101 @@
<?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>Closing Database Environments</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Env.html" title="Chapter 2. Database Environments" />
<link rel="previous" href="Env.html" title="Chapter 2. Database Environments" />
<link rel="next" href="EnvProps.html" title="Environment Properties" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Closing Database Environments</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="Env.html">Prev</a> </td>
<th width="60%" align="center">Chapter 2. Database Environments</th>
<td width="20%" align="right"> <a accesskey="n" href="EnvProps.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="EnvClose"></a>Closing Database Environments</h2>
</div>
</div>
<div></div>
</div>
<p>
You close your environment by calling the
<tt class="methodname">Environment.close()</tt>
method. This method performs a checkpoint, so it is not necessary to perform a sync or a checkpoint explicitly
before calling it. For information on checkpoints, see the
<i class="citetitle">Berkeley DB Java Edition Getting Started with Transaction Processing</i> guide.
For information on syncs, see
<span>
the <i class="citetitle">Getting Started with Transaction Processing for Java</i> guide.
</span>
</p>
<pre class="programlisting">import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
...
try {
if (myDbEnvironment != null) {
myDbEnvironment.close();
}
} catch (DatabaseException dbe) {
// Exception handling goes here
} </pre>
<p>You should close your environment(s) only after all other
database activities have completed and you have closed any databases
currently opened in the environment.</p>
<p>
Closing the last environment handle in your application causes all
internal data structures to be
<span>
released.
</span>
If there are any opened databases or stores,
then DB will complain before closing them as well.
At this time, any open cursors are also closed, and any on-going transactions are aborted.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="Env.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Env.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="EnvProps.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 2. Database Environments </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Environment Properties</td>
</tr>
</table>
</div>
</body>
</html>

246
docs/gsg/JAVA/EnvProps.html Normal file
View File

@@ -0,0 +1,246 @@
<?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>Environment Properties</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Env.html" title="Chapter 2. Database Environments" />
<link rel="previous" href="EnvClose.html" title="Closing Database Environments" />
<link rel="next" href="dpl.html" title="Part I. Programming with the Direct Persistence Layer" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Environment Properties</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="EnvClose.html">Prev</a> </td>
<th width="60%" align="center">Chapter 2. Database Environments</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl.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="EnvProps"></a>Environment Properties</h2>
</div>
</div>
<div></div>
</div>
<p>You set properties for the <tt class="classname">Environment</tt> using
the <tt class="classname">EnvironmentConfig</tt> class. You can also set properties for a specific
<tt class="classname">Environment</tt> instance using <tt class="classname">EnvironmentMutableConfig</tt>.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="envconfig"></a>The EnvironmentConfig Class</h3>
</div>
</div>
<div></div>
</div>
<p>
The <tt class="classname">EnvironmentConfig</tt> class makes a
large number of fields and methods available to you. Describing all of these
tuning parameters is beyond the scope of this manual. However, there are a
few properties that you are likely to want to set. They are described
here.</p>
<p>Note that for each of the properties that you can commonly set, there is a
corresponding getter method. Also, you can always retrieve the
<tt class="classname">EnvironmentConfig</tt> object used by your environment
using the <tt class="methodname">Environment.getConfig()</tt> method.
</p>
<p>
You set environment configuration parameters using the following methods on the
<tt class="classname">EnvironmentConfig</tt> class:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">EnvironmentConfig.setAllowCreate()</tt>
</p>
<p>If <tt class="literal">true</tt>, the database environment is created
when it is opened. If <tt class="literal">false</tt>, environment open fails if the environment
does not exist. This property has no meaning if the database
environment already exists. Default is <tt class="literal">false</tt>.</p>
</li>
<li>
<p>
<tt class="methodname">EnvironmentConfig.setReadOnly()</tt>
</p>
<p>If <tt class="literal">true</tt>, then all databases opened in this
environment must be opened as read-only. If you are writing a
multi-process application, then all but one of your processes must set
this value to <tt class="literal">true</tt>. Default is <tt class="literal">false</tt>.</p>
</li>
<li>
<p>
<tt class="methodname">EnvironmentConfig.setTransactional()</tt>
</p>
<p>If <tt class="literal">true</tt>, configures the database environment
to support transactions. Default is <tt class="literal">false</tt>.</p>
</li>
</ul>
</div>
<p>For example:</p>
<pre class="programlisting">package db.gettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import java.io.File;
import java.io.FileNotFoundException;
...
Environment myDatabaseEnvironment = null;
try {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
envConfig.setTransactional(true);
myDatabaseEnvironment =
new Environment(new File("/export/dbEnv"), envConfig);
} catch (DatabaseException dbe) {
System.err.println(dbe.toString());
System.exit(1);
} catch (FileNotFoundException fnfe) {
System.err.println(fnfe.toString());
System.exit(-1);
} </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="envhandleconfig"></a>EnvironmentMutableConfig</h3>
</div>
</div>
<div></div>
</div>
<p>
<tt class="classname">EnvironmentMutableConfig</tt> manages properties that can be reset after the
<tt class="classname">Environment</tt> object has been constructed. In addition, <tt class="classname">EnvironmentConfig</tt>
extends <tt class="classname">EnvironmentMutableConfig</tt>, so you can set these mutable properties at
<tt class="classname">Environment</tt> construction time if necessary.
</p>
<p>
The <tt class="classname">EnvironmentMutableConfig</tt> class allows you to set the following
properties:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="literal">setCachePercent()</tt>
</p>
<p>
Determines the percentage of JVM memory available to the DB cache.
See <a href="cachesize.html">Selecting the Cache Size</a>
for more information.
</p>
</li>
<li>
<p>
<tt class="literal">setCacheSize()</tt>
</p>
<p>
Determines the total amount of memory available to the database cache.
See <a href="cachesize.html">Selecting the Cache Size</a>
for more information.
</p>
</li>
<li>
<p>
<tt class="literal">setTxnNoSync()</tt>
</p>
<p>
Determines whether change records created due to a transaction commit are written to the backing
log files on disk. A value of <tt class="literal">true</tt> causes
the data to not be flushed to
disk. See the
<i class="citetitle">Getting Started with Transaction Processing for Java</i>
guide for more information.
</p>
</li>
<li>
<p>
<tt class="literal">setTxnWriteNoSync()</tt>
</p>
<p>
Determines whether logs are flushed on transaction commit (the logs are still written, however).
By setting this value to <tt class="literal">true</tt>, you potentially gain better performance than if
you flush the logs on commit, but you do so by losing some of your transaction durability guarantees.
See the
<i class="citetitle">Getting Started with Transaction Processing for Java</i>
guide for more information.
</p>
</li>
</ul>
</div>
<p>
There is also a corresponding getter method (<tt class="methodname">getTxnNoSync()</tt>).
Moreover, you can always retrieve your environment's
<tt class="classname">EnvironmentMutableConfig</tt> object by
using the <tt class="methodname">Environment.getMutableConfig()</tt> method.
</p>
<p>
For example:
</p>
<pre class="programlisting">package db.gettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentMutableConfig;
import java.io.File;
import java.io.FileNotFoundException;
...
try {
Environment myEnv = new Environment(new File("/export/dbEnv"), null);
EnvironmentMutableConfig envMutableConfig =
new EnvironmentMutableConfig();
envMutableConfig.setTxnNoSync(true);
myEnv.setMutableConfig(envMutableConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
}</pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="EnvClose.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Env.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Closing Database Environments </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Part I. Programming with the Direct Persistence Layer</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,597 @@
<?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>Getting Records Using the Cursor</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Cursors.html" title="Chapter 9. Using Cursors" />
<link rel="previous" href="Cursors.html" title="Chapter 9. Using Cursors" />
<link rel="next" href="PutEntryWCursor.html" title="Putting Records Using Cursors" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Getting Records Using the Cursor</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="Cursors.html">Prev</a> </td>
<th width="60%" align="center">Chapter 9. Using Cursors</th>
<td width="20%" align="right"> <a accesskey="n" href="PutEntryWCursor.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="Positioning"></a>Getting Records Using the Cursor</h2>
</div>
</div>
<div></div>
</div>
<p>
To iterate over database records, from the first record to
the last, simply open the cursor and then use the
<tt class="methodname">Cursor.getNext()</tt>
method.
For example:
</p>
<a id="java_cursor3"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Cursor cursor = null;
try {
...
Database myDatabase = null;
// Database open omitted for brevity
...
// Open the cursor.
cursor = myDatabase.openCursor(null, null);
// Cursors need a pair of DatabaseEntry objects to operate. These hold
// the key and data found at any given position in the database.
DatabaseEntry foundKey = new DatabaseEntry();
DatabaseEntry foundData = new DatabaseEntry();
// To iterate, just call getNext() until the last database record has been
// read. All cursor operations return an OperationStatus, so just read
// until we no longer see OperationStatus.SUCCESS
while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
// getData() on the DatabaseEntry objects returns the byte array
// held by that object. We use this to get a String value. If the
// DatabaseEntry held a byte array representation of some other data
// type (such as a complex object) then this operation would look
// considerably different.
String keyString = new String(foundKey.getData(), "UTF-8");
String dataString = new String(foundData.getData(), "UTF-8");
System.out.println("Key | Data : " + keyString + " | " +
dataString + "");
}
} catch (DatabaseException de) {
System.err.println("Error accessing database." + de);
} finally {
// Cursors must be closed.
cursor.close();
}</pre>
<p>
To iterate over the database from the last record to the first,
instantiate the cursor, and then
use <tt class="methodname">Cursor.getPrev()</tt> until you read the first record in
the database. For example:
</p>
<a id="java_cursor4"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Cursor cursor = null;
Database myDatabase = null;
try {
...
// Database open omitted for brevity
...
// Open the cursor.
cursor = myDatabase.openCursor(null, null);
// Get the DatabaseEntry objects that the cursor will use.
DatabaseEntry foundKey = new DatabaseEntry();
DatabaseEntry foundData = new DatabaseEntry();
// Iterate from the last record to the first in the database
while (cursor.getPrev(foundKey, foundData, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
String theKey = new String(foundKey.getData(), "UTF-8");
String theData = new String(foundData.getData(), "UTF-8");
System.out.println("Key | Data : " + theKey + " | " + theData + "");
}
} catch (DatabaseException de) {
System.err.println("Error accessing database." + de);
} finally {
// Cursors must be closed.
cursor.close();
}</pre>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="cursorsearch"></a>Searching for Records</h3>
</div>
</div>
<div></div>
</div>
<p>
You can use cursors to search for database records. You can search based
on just a key, or you can search based on both the key and the data.
You can also perform partial matches if your database supports sorted
duplicate sets. In all cases, the key and data parameters of these
methods are filled with the key and data values of the database record
to which the cursor is positioned as a result of the search.
</p>
<p>
Also, if the search fails, then cursor's state is left unchanged
and
<tt class="literal">OperationStatus.NOTFOUND</tt>
is returned.
</p>
<p>
The following <tt class="classname">Cursor</tt> methods allow you to
perform database searches:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">Cursor.getSearchKey()</tt>
</p>
<p>
Moves the cursor to the first record in the database with
the specified key.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.getSearchKeyRange()</tt>
</p>
<p>
<span>Identical to
<tt class="methodname">Cursor.getSearchKey()</tt>
unless you are using the BTree access. In this case, the cursor
moves</span>
to the first record in the database whose
key is greater than or equal to the specified key. This comparison
is determined by the
<span>comparator</span>
that you provide for the database. If no
<span>comparator</span>
is provided, then the default
lexicographical sorting is used.
</p>
<p>
For example, suppose you have database records that use the
following
<span>Strings</span>
as keys:
</p>
<pre class="programlisting">Alabama
Alaska
Arizona</pre>
<p>
Then providing a search key of <tt class="literal">Alaska</tt> moves the
cursor to the second key noted above. Providing a key of
<tt class="literal">Al</tt> moves the cursor to the first key (<tt class="literal">Alabama</tt>), providing
a search key of <tt class="literal">Alas</tt> moves the cursor to the second key
(<tt class="literal">Alaska</tt>), and providing a key of <tt class="literal">Ar</tt> moves the
cursor to the last key (<tt class="literal">Arizona</tt>).
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.getSearchBoth()</tt>
</p>
<p>
Moves the cursor to the first record in the database that uses
the specified key and data.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.getSearchBothRange()</tt>
</p>
<p>
Moves the cursor to the first record in the database whose key matches the specified
key and whose data is
greater than or equal to the specified data. If the database supports
duplicate records, then on matching the key, the cursor is moved to
the duplicate record with the smallest data that is greater than or
equal to the specified data.
</p>
<p>
For example,
<span>suppose your database uses BTree
and it has </span>
database records that use the following key/data pairs:
</p>
<pre class="programlisting">Alabama/Athens
Alabama/Florence
Alaska/Anchorage
Alaska/Fairbanks
Arizona/Avondale
Arizona/Florence </pre>
<p>then providing:</p>
<div class="informaltable">
<table border="1" width="80%">
<colgroup>
<col />
<col />
<col />
</colgroup>
<thead>
<tr>
<th>a search key of ...</th>
<th>and a search data of ...</th>
<th>moves the cursor to ...</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alaska</td>
<td>Fa</td>
<td>Alaska/Fairbanks</td>
</tr>
<tr>
<td>Arizona</td>
<td>Fl</td>
<td>Arizona/Florence</td>
</tr>
<tr>
<td>Alaska</td>
<td>An</td>
<td>Alaska/Anchorage</td>
</tr>
</tbody>
</table>
</div>
</li>
</ul>
</div>
<p>
For example, assuming a database containing sorted duplicate records of
U.S. States/U.S Cities key/data pairs (both as
<span>Strings),</span>
then the following code fragment can be used to position the cursor
to any record in the database and print its key/data values:
</p>
<a id="java_cursor5"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
// For this example, hard code the search key and data
String searchKey = "Alaska";
String searchData = "Fa";
Cursor cursor = null;
Database myDatabase = null;
try {
...
// Database open omitted for brevity
...
// Open the cursor.
cursor = myDatabase.openCursor(null, null);
DatabaseEntry theKey =
new DatabaseEntry(searchKey.getBytes("UTF-8"));
DatabaseEntry theData =
new DatabaseEntry(searchData.getBytes("UTF-8"));
// Open a cursor using a database handle
cursor = myDatabase.openCursor(null, null);
// Perform the search
OperationStatus retVal = cursor.getSearchBothRange(theKey, theData,
LockMode.DEFAULT);
// NOTFOUND is returned if a record cannot be found whose key
// matches the search key AND whose data begins with the search data.
if (retVal == OperationStatus.NOTFOUND) {
System.out.println(searchKey + "/" + searchData +
" not matched in database " +
myDatabase.getDatabaseName());
} else {
// Upon completing a search, the key and data DatabaseEntry
// parameters for getSearchBothRange() are populated with the
// key/data values of the found record.
String foundKey = new String(theKey.getData(), "UTF-8");
String foundData = new String(theData.getData(), "UTF-8");
System.out.println("Found record " + foundKey + "/" + foundData +
"for search key/data: " + searchKey +
"/" + searchData);
}
} catch (Exception e) {
// Exception handling goes here
} finally {
// Make sure to close the cursor
cursor.close();
}</pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="getdups"></a>Working with Duplicate Records</h3>
</div>
</div>
<div></div>
</div>
<p>
A record is a duplicate of another record if the two records share the
same key. For duplicate records, only the data portion of the record is unique.
</p>
<p>
Duplicate records are supported only for the BTree or Hash access methods.
For information on configuring your database to use duplicate records,
see <a href="btree.html#duplicateRecords">Allowing Duplicate Records</a>.
</p>
<p>
If your database supports duplicate records, then it can potentially
contain multiple records that share the same key.
<span>By default, normal database
get operations will only return the first such record in a set
of duplicate records. Typically, subsequent duplicate records are
accessed using a cursor.
</span>
The following
<span><tt class="methodname">Cursor</tt> methods</span>
are interesting when working with databases that support duplicate records:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<span>
<tt class="methodname">Cursor.getNext()</tt>,
<tt class="methodname">Cursor.getPrev()</tt>
</span>
</p>
<p>
Shows the next/previous record in the database, regardless of
whether it is a duplicate of the current record. For an example of
using these methods, see <a href="Positioning.html">Getting Records Using the Cursor</a>.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.getSearchBothRange()</tt>
</p>
<p>
Useful for seeking the cursor to a specific record, regardless of
whether it is a duplicate record. See <a href="Positioning.html#cursorsearch">Searching for Records</a> for more
information.
</p>
</li>
<li>
<p>
<span>
<tt class="methodname">Cursor.getNextNoDup()</tt>,
<tt class="methodname">Cursor.getPrevNoDup()</tt>
</span>
</p>
<p>
Gets the next/previous non-duplicate record in the database. This
allows you to skip over all the duplicates in a set of duplicate
records. If you call
<span><tt class="methodname">Cursor.getPrevNoDup()</tt>,</span>
then the cursor is positioned to the last record for the previous
key in the database. For example, if you have the following records
in your database:
</p>
<pre class="programlisting">Alabama/Athens
Alabama/Florence
Alaska/Anchorage
Alaska/Fairbanks
Arizona/Avondale
Arizona/Florence</pre>
<p>
and your cursor is positioned to <tt class="literal">Alaska/Fairbanks</tt>,
and you then call
<span><tt class="methodname">Cursor.getPrevNoDup()</tt>,</span>
then the cursor is positioned to Alabama/Florence. Similarly, if
you call
<span><tt class="methodname">Cursor.getNextNoDup()</tt>,</span>
then the cursor is positioned to the first record corresponding to
the next key in the database.
</p>
<p>
If there is no next/previous key in the database, then
<tt class="literal">OperationStatus.NOTFOUND</tt>
is returned, and the cursor is left unchanged.
</p>
</li>
<li>
<p>
</p>
<p>
Gets the
<span>next</span>
record that shares the current key. If the
cursor is positioned at the last record in the duplicate set and
you call
<span><tt class="methodname">Cursor.getNextDup()</tt>,</span>
then
<tt class="literal">OperationStatus.NOTFOUND</tt>
is returned and the cursor is left unchanged.
<span>
Likewise, if you call
<tt class="methodname">getPrevDup()</tt> and the
cursor is positioned at the first record in the duplicate set, then
<tt class="literal">OperationStatus.NOTFOUND</tt> is returned and the
cursor is left unchanged.
</span>
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.count()</tt>
</p>
<p>Returns the total number of records that share the current key.</p>
</li>
</ul>
</div>
<p>
For example, the following code fragment positions a cursor to a key
<span>and displays it and all its
duplicates.</span>
<span>Note that the following code fragment assumes that the database contains
only String objects for the keys and data.</span>
</p>
<a id="java_cursor6"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Cursor cursor = null;
Database myDatabase = null;
try {
...
// Database open omitted for brevity
...
// Create DatabaseEntry objects
// searchKey is some String.
DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
// Open a cursor using a database handle
cursor = myDatabase.openCursor(null, null);
// Position the cursor
// Ignoring the return value for clarity
OperationStatus retVal = cursor.getSearchKey(theKey, theData,
LockMode.DEFAULT);
// Count the number of duplicates. If the count is greater than 1,
// print the duplicates.
if (cursor.count() &gt; 1) {
while (retVal == OperationStatus.SUCCESS) {
String keyString = new String(theKey.getData(), "UTF-8");
String dataString = new String(theData.getData(), "UTF-8");
System.out.println("Key | Data : " + keyString + " | " +
dataString + "");
retVal = cursor.getNextDup(theKey, theData, LockMode.DEFAULT);
}
}
} catch (Exception e) {
// Exception handling goes here
} finally {
// Make sure to close the cursor
cursor.close();
}</pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="Cursors.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Cursors.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="PutEntryWCursor.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 9. Using Cursors </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Putting Records Using Cursors</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,206 @@
<?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>Putting Records Using Cursors</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Cursors.html" title="Chapter 9. Using Cursors" />
<link rel="previous" href="Positioning.html" title="Getting Records Using the Cursor" />
<link rel="next" href="DeleteEntryWCursor.html" title="Deleting Records Using Cursors" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Putting Records Using Cursors</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="Positioning.html">Prev</a> </td>
<th width="60%" align="center">Chapter 9. Using Cursors</th>
<td width="20%" align="right"> <a accesskey="n" href="DeleteEntryWCursor.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="PutEntryWCursor"></a>Putting Records Using Cursors</h2>
</div>
</div>
<div></div>
</div>
<p>
You can use cursors to put records into the database. DB's behavior
when putting records into the database differs depending on the flags
that you use when writing the record, on the access method that you are
using, and on whether your database supports sorted duplicates.
</p>
<p>
Note that when putting records to the database using a cursor, the
cursor is positioned at the record you inserted.
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">Cursor.putNoDupData()</tt>
</p>
<p>
If the provided key already exists
in the database, then this method returns
<tt class="literal">OperationStatus.KEYEXIST</tt>.
</p>
<p>
If the key does not exist, then the order that the record is put into the database
is determined by the
<span>
insertion order in use by the database. If a comparison
function has been provided to the database, the record is
inserted in its sorted location. Otherwise (assuming BTree),
lexicographical sorting is used, with
shorter items collating before longer items.
</span>
</p>
<p>
This flag can only be used for the BTree and Hash access methods,
and only if the database has been configured to support sorted
duplicate data items (<tt class="literal">DB_DUPSORT</tt> was specified at
database creation time).
</p>
<p>
This flag cannot be used with the Queue or Recno access methods.
</p>
<p>
For more information on duplicate records, see
<a href="btree.html#duplicateRecords">Allowing Duplicate Records</a>.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.putNoOverwrite()</tt>
</p>
<p>
If the provided key already exists
in the database, then this method returns
.
</p>
<p>
If the key does not exist, then the order that the record is put into the database
is determined by the BTree (key) comparator in use by the database.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.putKeyFirst()</tt>
</p>
<p>
For databases that do not support duplicates, this method behaves
<span>
exactly the same as if a default insertion was performed.
</span>
If the database supports duplicate records,
<span>
and a duplicate sort function has been specified, the
inserted data item is added in its sorted location. If
the key already exists in the database and no duplicate
sort function has been specified, the inserted data item
is added as the first of the data items for that key.
</span>
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.putKeyLast()</tt>
</p>
<p>
Behaves exactly as if
<tt class="methodname">Cursor.putKeyFirst()</tt>
was used, except that if the key already exists in the database and no
duplicate sort function has been specified, the
inserted data item is added as the last of the data
items for that key.
</p>
</li>
</ul>
</div>
<p>For example:</p>
<a id="java_cursor7"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.OperationStatus;
...
// Create the data to put into the database
String key1str = "My first string";
String data1str = "My first data";
String key2str = "My second string";
String data2str = "My second data";
String data3str = "My third data";
Cursor cursor = null;
Database myDatabase = null;
try {
...
// Database open omitted for brevity
...
DatabaseEntry key1 = new DatabaseEntry(key1str.getBytes("UTF-8"));
DatabaseEntry data1 = new DatabaseEntry(data1str.getBytes("UTF-8"));
DatabaseEntry key2 = new DatabaseEntry(key2str.getBytes("UTF-8"));
DatabaseEntry data2 = new DatabaseEntry(data2str.getBytes("UTF-8"));
DatabaseEntry data3 = new DatabaseEntry(data3str.getBytes("UTF-8"));
// Open a cursor using a database handle
cursor = myDatabase.openCursor(null, null);
// Assuming an empty database.
OperationStatus retVal = cursor.put(key1, data1); // SUCCESS
retVal = cursor.put(key2, data2); // SUCCESS
retVal = cursor.put(key2, data3); // SUCCESS if dups allowed,
// KEYEXIST if not.
} catch (Exception e) {
// Exception handling goes here
} finally {
// Make sure to close the cursor
cursor.close();
}</pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="Positioning.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Cursors.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="DeleteEntryWCursor.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Getting Records Using the Cursor </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Deleting Records Using Cursors</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,132 @@
<?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>Replacing Records Using Cursors</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Cursors.html" title="Chapter 9. Using Cursors" />
<link rel="previous" href="DeleteEntryWCursor.html" title="Deleting Records Using Cursors" />
<link rel="next" href="cursorJavaUsage.html" title="Cursor Example" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Replacing Records Using Cursors</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="DeleteEntryWCursor.html">Prev</a> </td>
<th width="60%" align="center">Chapter 9. Using Cursors</th>
<td width="20%" align="right"> <a accesskey="n" href="cursorJavaUsage.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="ReplacingEntryWCursor"></a>Replacing Records Using Cursors</h2>
</div>
</div>
<div></div>
</div>
<p>
You replace the data for a database record by using
<span>
<tt class="methodname">Cursor.putCurrent()</tt>.
</span>
</p>
<a id="java_cursor9"></a>
<pre class="programlisting">import com.sleepycat.db.Cursor;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Cursor cursor = null;
Database myDatabase = null;
try {
...
// Database open omitted for brevity
...
// Create DatabaseEntry objects
// searchKey is some String.
DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
// Open a cursor using a database handle
cursor = myDatabase.openCursor(null, null);
// Position the cursor. Ignoring the return value for clarity
OperationStatus retVal = cursor.getSearchKey(theKey, theData,
LockMode.DEFAULT);
// Replacement data
String replaceStr = "My replacement string";
DatabaseEntry replacementData =
new DatabaseEntry(replaceStr.getBytes("UTF-8"));
cursor.putCurrent(replacementData);
} catch (Exception e) {
// Exception handling goes here
} finally {
// Make sure to close the cursor
cursor.close();
}</pre>
<p>
Note that you cannot change a record's key using this method; the key
parameter is always ignored when you replace a record.
</p>
<p>
When replacing the data portion of a record, if you are replacing a
record that is a member of a sorted duplicates set, then the replacement
will be successful only if the new record sorts identically to the old
record. This means that if you are replacing a record that is a member
of a sorted duplicates set, and if you are using the default
lexicographic sort, then the replacement will fail due to violating the
sort order. However, if you
provide a custom sort routine that, for example, sorts based on just a
few bytes out of the data item, then potentially you can perform
a direct replacement and still not violate the restrictions described
here.
</p>
<p>
<span>Under these circumstances, if</span>
you want to replace the data contained by a duplicate record,
<span>
and you are not using a custom sort routine, then
</span>
delete the record and create a new record with the desired key and data.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="DeleteEntryWCursor.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Cursors.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="cursorJavaUsage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Deleting Records Using Cursors </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Cursor Example</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,289 @@
<?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>Access Methods</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="javadplconcepts.html" title="Berkeley DB Concepts" />
<link rel="next" href="databaseLimits.html" title="Database Limits and Portability" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Access Methods</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="javadplconcepts.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="databaseLimits.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="accessmethods"></a>Access Methods</h2>
</div>
</div>
<div></div>
</div>
<p>
While this manual will focus primarily on the BTree access method, it is
still useful to briefly describe all of the access methods that DB
makes available.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
If you are using the DPL, be aware that it only
supports the BTree access method. For that reason, you
can skip this section.
</p>
</div>
<p>
Note that an access method can be selected only when the database is
created. Once selected, actual API usage is generally
identical across all access methods. That is, while some
exceptions exist, mechanically you interact with the library in the same
way regardless of which access method you have selected.
</p>
<p>
The access method that you should choose is gated first by what you want
to use as a key, and then secondly by the performance that you see
for a given access method.
</p>
<p>
The following are the available access methods:
</p>
<div class="informaltable">
<table border="1" width="80%">
<colgroup>
<col align="left" />
<col align="left" />
</colgroup>
<thead>
<tr>
<th align="center">Access Method</th>
<th align="center">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">BTree</td>
<td align="left" valign="top">
<p>
Data is stored in a sorted, balanced tree structure.
Both the key and the data for BTree records can be
arbitrarily complex. That is, they can contain single values
such as an integer or a string, or complex types such as a
structure. Also, although not the default
behavior, it is possible for two records to
use keys that compare as equals. When this occurs, the
records are considered to be duplicates of one another.
</p>
</td>
</tr>
<tr>
<td align="left">Hash</td>
<td align="left" valign="top">
<p>
Data is stored in an extended linear hash table. Like
BTree, the key and the data used for Hash records can be of
arbitrarily complex data. Also, like BTree, duplicate
records are optionally supported.
</p>
</td>
</tr>
<tr>
<td align="left">Queue</td>
<td align="left" valign="top">
<p>
Data is stored in a queue as fixed-length records. Each
record uses a logical record number as its key. This access
method is designed for fast inserts at the tail of the
queue, and it has a special operation that deletes and
returns a record from the head of the queue.
</p>
<p>
This access method is unusual in that it provides record
level locking. This can provide
beneficial performance improvements in applications
requiring concurrent access to the queue.
</p>
</td>
</tr>
<tr>
<td align="left">Recno</td>
<td align="left" valign="top">
<p>
Data is stored in either fixed or variable-length records.
Like Queue, Recno records use logical record numbers as keys.
</p>
</td>
</tr>
</tbody>
</table>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="selectAM"></a>Selecting Access Methods</h3>
</div>
</div>
<div></div>
</div>
<p>
To select an access method, you should first consider what you want
to use as a key for you database records. If you want to use
arbitrary data (even strings), then you should use either BTree or
Hash. If you want to use logical record numbers (essentially
integers) then you should use Queue or Recno.
</p>
<p>
Once you have made this decision, you must choose between either
BTree or Hash, or Queue or Recno. This decision is described next.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="BTreeVSHash"></a>Choosing between BTree and Hash</h3>
</div>
</div>
<div></div>
</div>
<p>
For small working datasets that fit entirely in memory, there is no
difference between BTree and Hash. Both will perform just as well
as the other. In this situation, you might just as well use BTree,
if for no other reason than the majority of DB applications use
BTree.
</p>
<p>
Note that the main concern here is your
working dataset, not your entire dataset. Many applications maintain
large amounts of information but only need to access some small
portion of that data with any frequency. So what you want to
consider is the data that you will routinely use, not the sum total
of all the data managed by your application.
</p>
<p>
However, as your working dataset grows to the point
where you cannot fit it all into memory, then you need to take more
care when choosing your access method. Specifically, choose:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
BTree if your keys have some locality of reference. That is,
if they sort well and you can expect that a query for a
given key will likely be followed by a query for one of its
neighbors.
</p>
</li>
<li>
<p>
Hash if your dataset is extremely large. For any given
access method, DB must maintain a certain amount of internal
information. However, the amount of information that DB
must maintain for BTree is much greater than for Hash. The
result is that as your dataset grows, this internal
information can dominate the cache to the point where there
is relatively little space left for application data.
As a result, BTree can be forced to perform disk I/O much more
frequently than would Hash given the same amount of data.
</p>
<p>
Moreover, if your dataset becomes so large that DB will
almost certainly have to perform disk I/O to satisfy a
random request, then Hash will definitely out perform BTree
because it has fewer internal records to search through than
does BTree.
</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="QueueVSRecno"></a>Choosing between Queue and Recno</h3>
</div>
</div>
<div></div>
</div>
<p>
Queue or Recno are used when the application wants to use logical
record numbers for the primary database key. Logical record numbers
are essentially integers that uniquely identify the database
record. They can be either mutable or fixed, where a mutable record
number is one that might change as database records are stored or
deleted. Fixed logical record numbers never change regardless of
what database operations are performed.
</p>
<p>
When deciding between Queue and Recno, choose:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Queue if your application requires high degrees of
concurrency. Queue provides record-level locking (as opposed
to the page-level locking that the other access methods
use), and this can result in significantly faster throughput
for highly concurrent applications.
</p>
<p>
Note, however, that Queue provides support only for fixed
length records. So if the size of the data that you want to
store varies widely from record to record, you should
probably choose an access method other than Queue.
</p>
</li>
<li>
<p>
Recno if you want mutable record numbers. Queue is only
capable of providing fixed record numbers. Also, Recno
provides support for databases whose permanent storage is a
flat text file. This is useful for applications looking for
fast, temporary storage while the data is being read or
modified.
</p>
</li>
</ul>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="javadplconcepts.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="databaseLimits.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Berkeley DB Concepts </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Database Limits and Portability</td>
</tr>
</table>
</div>
</body>
</html>

405
docs/gsg/JAVA/baseapi.html Normal file
View File

@@ -0,0 +1,405 @@
<?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>Part II. Programming with the Base API</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="previous" href="dpl_exampleinventoryread.html" title="ExampleInventoryRead.class" />
<link rel="next" href="DB.html" title="Chapter 7. Databases" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Part II. Programming with the Base API</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl_exampleinventoryread.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="DB.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="part" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a id="baseapi"></a>Programming with the Base API</h1>
</div>
</div>
<div></div>
</div>
<div class="partintro" lang="en" xml:lang="en">
<div>
<div></div>
<div></div>
</div>
<p>
This section discusses
application that are built using the DB base API. Note that
most DB applications can probably be written
using the DPL (see <a href="dpl.html">Programming with the Direct Persistence Layer</a> for more
information). However, if
you want to use Java 1.4 for your DB
application, or if you are porting an application
from the Berkeley DB API, then the base API is right for
you.
</p>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="chapter">
<a href="DB.html">7. Databases</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="DB.html#DBOpen">Opening Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="coredbclose.html">Closing Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DBConfig.html">Database Properties</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DBAdmin.html">Administrative Methods</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dbErrorReporting.html">Error Reporting Functions</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="CoreEnvUsage.html">Managing Databases in Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="CoreJavaUsage.html">Database Example</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="DBEntry.html">8. Database Records</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="DBEntry.html#usingDbEntry">Using Database Records</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="usingDbt.html">Reading and Writing Database Records</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="usingDbt.html#databaseWrite">Writing Records to the Database</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#databaseRead">Getting Records from the Database</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#recordDelete">Deleting Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#datapersist">Data Persistence</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="bindAPI.html">Using the BIND APIs</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="bindAPI.html#bindPrimitive">Numerical and String Objects</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="bindAPI.html#object2dbt">Serializable Complex Objects</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="bindAPI.html#customTuple">Custom Tuple Bindings</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dbtJavaUsage.html">Database Usage Example</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="Cursors.html">9. Using Cursors</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="Cursors.html#openCursor">Opening and Closing Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="Positioning.html">Getting Records Using the Cursor</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="Positioning.html#cursorsearch">Searching for Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="Positioning.html#getdups">Working with Duplicate Records</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="PutEntryWCursor.html">Putting Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DeleteEntryWCursor.html">Deleting Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="ReplacingEntryWCursor.html">Replacing Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="cursorJavaUsage.html">Cursor Example</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="indexes.html">10. Secondary Databases</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="indexes.html#DbAssociate">Opening and Closing Secondary Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="keyCreator.html">Implementing Key
Creators
</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="keyCreator.html#multikeys">Working with Multiple Keys</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="secondaryProps.html">Secondary Database Properties</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="readSecondary.html">Reading Secondary Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="secondaryDelete.html">Deleting Secondary Database Records</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="secondaryCursor.html">
Using Secondary Cursors
</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="joins.html">Database Joins</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="joins.html#joinUsage">Using Join Cursors</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="joins.html#joinconfig">JoinCursor Properties</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="javaindexusage.html">Secondary Database Example</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="javaindexusage.html#secondaryMyDbs">Opening Secondary Databases with MyDbs</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javaindexusage.html#exampleReadJavaSecondaries">Using Secondary Databases with ExampleDatabaseRead</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="dbconfig.html">11. Database Configuration</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="dbconfig.html#pagesize">Setting the Page Size</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="dbconfig.html#overflowpages">Overflow Pages</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#Locking">Locking</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#IOEfficiency">IO Efficiency</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#pagesizeAdvice">Page Sizing Advice</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="cachesize.html">Selecting the Cache Size</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="btree.html">BTree Configuration</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="btree.html#duplicateRecords">Allowing Duplicate Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="btree.html#comparators">Setting Comparison Functions</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl_exampleinventoryread.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="index.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="DB.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">ExampleInventoryRead.class </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 7. Databases</td>
</tr>
</table>
</div>
</body>
</html>

766
docs/gsg/JAVA/bindAPI.html Normal file
View File

@@ -0,0 +1,766 @@
<?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>Using the BIND APIs</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DBEntry.html" title="Chapter 8. Database Records" />
<link rel="previous" href="usingDbt.html" title="Reading and Writing Database Records" />
<link rel="next" href="dbtJavaUsage.html" title="Database Usage Example" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Using the BIND APIs</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="usingDbt.html">Prev</a> </td>
<th width="60%" align="center">Chapter 8. Database Records</th>
<td width="20%" align="right"> <a accesskey="n" href="dbtJavaUsage.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="bindAPI"></a>Using the BIND APIs</h2>
</div>
</div>
<div></div>
</div>
<p>Except for Java String and boolean types, efficiently moving data in
and out of Java byte arrays for storage in a database can be a nontrivial
operation. To help you with this problem, DB provides the Bind APIs.
While these APIs are described in detail in the
<span>
<i class="citetitle">Berkeley DB Collections Tutorial</i>,
</span>
this section provides a brief introduction to using the Bind APIs with:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Single field numerical and string objects</p>
<p>Use this if you want to store a single numerical or string object,
such as <tt class="classname">Long</tt>, <tt class="classname">Double</tt>, or
<tt class="classname">String</tt>.</p>
</li>
<li>
<p>Complex objects that implement Java serialization.</p>
<p>Use this if you are storing objects that implement
<tt class="classname">Serializable</tt> and if you do not need to sort them.
</p>
</li>
<li>
<p>Non-serialized complex objects.</p>
<p>If you are storing objects that do not implement serialization,
you can create your own custom tuple bindings. Note that you should
use custom tuple bindings even if your objects are serializable if
you want to sort on that data.</p>
</li>
</ul>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="bindPrimitive"></a>Numerical and String Objects</h3>
</div>
</div>
<div></div>
</div>
<p>You can use the Bind APIs to store primitive data in a <tt class="classname">DatabaseEntry</tt>
object. That is, you can store a single field containing one of the following types:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="classname">String</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Character</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Boolean</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Byte</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Short</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Integer</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Long</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Float</tt>
</p>
</li>
<li>
<p>
<tt class="classname">Double</tt>
</p>
</li>
</ul>
</div>
<p>
To store primitive data using the Bind APIs:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Create an <tt class="classname">EntryBinding</tt> object.</p>
<p>When you do this, you use <tt class="classname">TupleBinding.getPrimitiveBinding()</tt>
to return an appropriate binding for the conversion.</p>
</li>
<li>
<p>Use the <tt class="classname">EntryBinding</tt> object to place
the numerical object on the <tt class="classname">DatabaseEntry</tt>.</p>
</li>
</ol>
</div>
<p>Once the data is stored in the DatabaseEntry, you can put it to
the database in whatever manner you wish. For example:</p>
<a id="java_dbt6"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
...
Database myDatabase = null;
// Database open omitted for clarity.
// Need a key for the put.
try {
String aKey = "myLong";
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
// Now build the DatabaseEntry using a TupleBinding
Long myLong = new Long(123456789l);
DatabaseEntry theData = new DatabaseEntry();
EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
myBinding.objectToEntry(myLong, theData);
// Now store it
myDatabase.put(null, theKey, theData);
} catch (Exception e) {
// Exception handling goes here
}</pre>
<p>Retrieval from the <tt class="classname">DatabaseEntry</tt> object is
performed in much the same way:</p>
<a id="java_dbt7"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Database myDatabase = null;
// Database open omitted for clarity
try {
// Need a key for the get
String aKey = "myLong";
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
// Need a DatabaseEntry to hold the associated data.
DatabaseEntry theData = new DatabaseEntry();
// Bindings need only be created once for a given scope
EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
// Get it
OperationStatus retVal = myDatabase.get(null, theKey, theData,
LockMode.DEFAULT);
String retKey = null;
if (retVal == OperationStatus.SUCCESS) {
// Recreate the data.
// Use the binding to convert the byte array contained in theData
// to a Long type.
Long theLong = (Long) myBinding.entryToObject(theData);
retKey = new String(theKey.getData(), "UTF-8");
System.out.println("For key: '" + retKey + "' found Long: '" +
theLong + "'.");
} else {
System.out.println("No record found for key '" + retKey + "'.");
}
} catch (Exception e) {
// Exception handling goes here
} </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="object2dbt"></a>Serializable Complex Objects</h3>
</div>
</div>
<div></div>
</div>
<p>Frequently your application requires you to store and manage
objects for your record data and/or keys. You may need to do this if you
are caching objects created by another process. You may also want to do
this if you want to store multiple data values on a record. When used
with just primitive data, or with objects containing a single data member,
DB database records effectively represent a single row in a two-column table.
By storing a complex object in the record, you can turn each record into
a single row in an <span class="emphasis"><em>n</em></span>-column table, where
<span class="emphasis"><em>n</em></span> is the number of data members contained by the
stored object(s).</p>
<p>In order to store objects in a
DB database, you must convert them to and from a <tt class="literal">byte</tt> array.
The first instinct for many Java programmers is to do this using Java
serialization. While this is functionally a correct solution, the result
is poor space-performance because this causes the class information
to be stored on every such database record. This information can be quite large
and it is redundant — the class information does not vary for serialized objects of the same type.
</p>
<p>
In other words, directly using serialization to place your objects into byte
arrays means that you will be storing a great deal of unnecessary information in
your database, which ultimately leads to larger databases and more expensive disk
I/O.
</p>
<p>The easiest way for you to solve this problem is to use the Bind
APIs to perform the serialization for you. Doing so causes the extra
object information to be saved off to a unique <tt class="classname">Database</tt>
dedicated for that purpose. This means that you do not have to duplicate
that information on each record in the <tt class="classname">Database</tt>
that your application is using to store its information.</p>
<p>
Note that when you use the Bind APIs to perform serialization, you still
receive all the benefits of serialization. You can still use arbitrarily
complex object graphs, and you still receive built-in class evolution
through the serialVersionUID (SUID) scheme. All of the Java
serialization rules apply without modification. For example, you can
implement Externalizable instead of Serializable.
</p>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="bindCaveats"></a>Usage Caveats</h4>
</div>
</div>
<div></div>
</div>
<p>Before using the Bind APIs to perform serialization, you may
want to consider writing your own custom tuple bindings. Specifically,
avoid serialization if:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
If you need to sort based on the objects your are storing.
The sort order is meaningless for the byte arrays that you
obtain through serialization. Consequently, you should not use serialization for keys if you
care about their sort order. You should
also not use serialization for record data if your
<tt class="classname">Database</tt> supports duplicate records and you care about sort order.
</p>
</li>
<li>
<p>
You want to minimize the size of your byte arrays. Even when using the Bind APIs to perform the
serialization the resulting <tt class="literal">byte</tt> array may be larger than necessary. You can achieve
more compact results by building your own custom tuple binding.
</p>
</li>
<li>
<p>
You want to optimize for speed. In general, custom tuple bindings are faster than serialization at
moving data in and out of <tt class="literal">byte</tt> arrays.
</p>
</li>
</ul>
</div>
<p>
For information on building your own custom tuple binding, see <a href="bindAPI.html#customTuple">Custom Tuple Bindings</a>.
</p>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="objectSerial"></a>Serializing Objects</h4>
</div>
</div>
<div></div>
</div>
<p>To store a serializable complex object using the
Bind APIs:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Implement java.io.Serializable in the class whose instances that
you want to store.
</p>
</li>
<li>
<p>Open (create) your databases. You need two. The first is the
database that you use to store your data. The second is used to
store the class information.</p>
</li>
<li>
<p>Instantiate a class catalog. You do this with
<tt class="classname">com.sleepycat.bind.serial.StoredClassCatalog</tt>,
and at that time you must provide a handle to an open database
that is used to store the class information.</p>
</li>
<li>
<p>Create an entry binding that uses <tt class="methodname">com.sleepycat.bind.serial.SerialBinding</tt>.</p>
</li>
<li>
<p>Instantiate an instance of the object that you want to
store, and place it in a <tt class="classname">DatabaseEntry</tt>
using the entry binding that you created in the previous step.</p>
</li>
</ol>
</div>
<p>
For example, suppose you want to store a long, double, and a
String as a record's data. Then you might create a class that
looks something like this:
</p>
<a id="java_dbt8"></a>
<pre class="programlisting">package db.GettingStarted;
import java.io.Serializable;
public class MyData implements Serializable {
private long longData;
private double doubleData;
private String description;
MyData() {
longData = 0;
doubleData = 0.0;
description = null;
}
public void setLong(long data) {
longData = data;
}
public void setDouble(double data) {
doubleData = data;
}
public void setDescription(String data) {
description = data;
}
public long getLong() {
return longData;
}
public double getDouble() {
return doubleData;
}
public String getDescription() {
return description;
}
}</pre>
<p>You can then store instances of this class as follows:</p>
<a id="java_dbt9"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseType;
...
// The key data.
String aKey = "myData";
// The data data
MyData data2Store = new MyData();
data2Store.setLong(123456789l);
data2Store.setDouble(1234.9876543);
data2Store.setDescription("A test instance of this class");
try {
// Open the database that you will use to store your data
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(true);
myDbConfig.setSortedDuplicates(true);
myDbConfig.setType(DatabaseType.BTREE);
Database myDatabase = new Database("myDb", null, myDbConfig);
// Open the database that you use to store your class information.
// The db used to store class information does not require duplicates
// support.
myDbConfig.setSortedDuplicates(false);
Database myClassDb = new Database("classDb", null, myDbConfig);
// Instantiate the class catalog
StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);
// Create the binding
EntryBinding dataBinding = new SerialBinding(classCatalog,
MyData.class);
// Create the DatabaseEntry for the key
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
// Create the DatabaseEntry for the data. Use the EntryBinding object
// that was just created to populate the DatabaseEntry
DatabaseEntry theData = new DatabaseEntry();
dataBinding.objectToEntry(data2Store, theData);
// Put it as normal
myDatabase.put(null, theKey, theData);
// Database and environment close omitted for brevity
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="objectDeserial"></a>Deserializing Objects</h4>
</div>
</div>
<div></div>
</div>
<p>Once an object is stored in the database, you can retrieve the
<tt class="classname">MyData</tt> objects from the retrieved
<tt class="classname">DatabaseEntry</tt> using the Bind APIs in much the
same way as is described above. For example:</p>
<a id="java_dbt10"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseType;
import com.sleepycat.db.LockMode;
...
// The key data.
String aKey = "myData";
try {
// Open the database that stores your data
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(false);
myDbConfig.setType(DatabaseType.BTREE);
Database myDatabase = new Database("myDb", null, myDbConfig);
// Open the database that stores your class information.
Database myClassDb = new Database("classDb", null, myDbConfig);
// Instantiate the class catalog
StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);
// Create the binding
EntryBinding dataBinding = new SerialBinding(classCatalog,
MyData.class);
// Create DatabaseEntry objects for the key and data
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
// Do the get as normal
myDatabase.get(null, theKey, theData, LockMode.DEFAULT);
// Recreate the MyData object from the retrieved DatabaseEntry using
// the EntryBinding created above
MyData retrievedData = (MyData) dataBinding.entryToObject(theData);
// Database and environment close omitted for brevity
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="customTuple"></a>Custom Tuple Bindings</h3>
</div>
</div>
<div></div>
</div>
<p>
If you want to store complex objects in your database, then you can use
tuple bindings to do this. While they are more work to write and
maintain than if you were to use serialization, the
<tt class="literal">byte</tt> array conversion is faster. In addition, custom
tuple bindings should allow you to create <tt class="literal">byte</tt> arrays
that are smaller than those created by serialization. Custom tuple
bindings also allow you to optimize your BTree comparisons, whereas
serialization does not.
</p>
<p>
For information on using serialization to store complex objects, see
<a href="bindAPI.html#object2dbt">Serializable Complex Objects</a>.
</p>
<p>To store complex objects using a custom tuple binding:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Implement the class whose instances that you want to store.
Note that you do not have to implement the Serializable interface.</p>
</li>
<li>
<p>Write a tuple binding using the <tt class="classname">com.sleepycat.bind.tuple.TupleBinding</tt>
class.</p>
</li>
<li>
<p>Open (create) your database. Unlike serialization, you only
need one.</p>
</li>
<li>
<p>Create an entry binding that uses the tuple binding that you
implemented in step 2.</p>
</li>
<li>
<p>Instantiate an instance of the object that you want to store,
and place it in a <tt class="classname">DatabaseEntry</tt> using the
entry binding that you created in the previous step.</p>
</li>
</ol>
</div>
<p>
For example, suppose you want to your keys to be instances of the
following class:
</p>
<a id="java_dbt11"></a>
<pre class="programlisting">package db.GettingStarted;
public class MyData2 {
private long longData;
private Double doubleData;
private String description;
public MyData2() {
longData = 0;
doubleData = new Double(0.0);
description = "";
}
public void setLong(long data) {
longData = data;
}
public void setDouble(Double data) {
doubleData = data;
}
public void setString(String data) {
description = data;
}
public long getLong() {
return longData;
}
public Double getDouble() {
return doubleData;
}
public String getString() {
return description;
}
} </pre>
<p>In this case, you need to write a tuple binding for the
<tt class="classname">MyData2</tt> class. When you do this, you must
implement the <tt class="methodname">TupleBinding.objectToEntry()</tt>
and <tt class="methodname">TupleBinding.entryToObject()</tt> abstract methods.
Remember the following as you implement these methods:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>You use <tt class="methodname">TupleBinding.objectToEntry()</tt> to convert
objects to <tt class="literal">byte</tt> arrays. You use
<tt class="classname">com.sleepycat.bind.tuple.TupleOutput</tt> to write
primitive data types to the <tt class="literal">byte</tt> array. Note that
<tt class="classname">TupleOutput</tt> provides methods that allows
you to work with numerical types (<tt class="literal">long</tt>,
<tt class="literal">double</tt>, <tt class="literal">int</tt>, and so forth) and
not the corresponding <tt class="literal">java.lang</tt> numerical
classes.</p>
</li>
<li>
<p>The order that you write data to the <tt class="literal">byte</tt>
array in <tt class="methodname">TupleBinding.objectToEntry()</tt> is the order that
it appears in the array. So given the <tt class="classname">MyData2</tt>
class as an example, if you write <tt class="literal">description</tt>,
<tt class="literal">doubleData</tt>, and then <tt class="literal">longData</tt>,
then the resulting byte array will contain these data elements in
that order. This means that your records will sort based on the
value of the <tt class="literal">description</tt> data member and then
the <tt class="literal">doubleData</tt> member, and so forth. If you
prefer to sort based on, say, the <tt class="literal">longData</tt> data
member, write it to the byte array first.</p>
</li>
<li>
<p>You use <tt class="methodname">TupleBinding.entryToObject()</tt> to convert
the <tt class="literal">byte</tt> array back into an instance of your
original class. You use <tt class="classname">com.sleepycat.bind.tuple.TupleInput</tt>
to get data from the <tt class="literal">byte</tt> array.</p>
</li>
<li>
<p>The order that you read data from the <tt class="literal">byte</tt>
array must be exactly the same as the order in which it was written.</p>
</li>
</ul>
</div>
<p>For example:</p>
<a id="java_dbt12"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
public class MyTupleBinding extends TupleBinding {
// Write a MyData2 object to a TupleOutput
public void objectToEntry(Object object, TupleOutput to) {
MyData2 myData = (MyData2)object;
// Write the data to the TupleOutput (a DatabaseEntry).
// Order is important. The first data written will be
// the first bytes used by the default comparison routines.
to.writeDouble(myData.getDouble().doubleValue());
to.writeLong(myData.getLong());
to.writeString(myData.getString());
}
// Convert a TupleInput to a MyData2 object
public Object entryToObject(TupleInput ti) {
// Data must be read in the same order that it was
// originally written.
Double theDouble = new Double(ti.readDouble());
long theLong = ti.readLong();
String theString = ti.readString();
MyData2 myData = new MyData2();
myData.setDouble(theDouble);
myData.setLong(theLong);
myData.setString(theString);
return myData;
}
} </pre>
<p>In order to use the tuple binding, instantiate the binding and
then use:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><tt class="methodname">MyTupleBinding.objectToEntry()</tt> to
convert a MyData2 object to a <tt class="classname">DatabaseEntry</tt>.</p>
</li>
<li>
<p><tt class="methodname">MyTupleBinding.entryToObject()</tt> to convert
a <tt class="classname">DatabaseEntry</tt> to a <tt class="classname">MyData2</tt>
object.</p>
</li>
</ul>
</div>
<p>For example:</p>
<a id="java_dbt13"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.DatabaseEntry;
...
TupleBinding keyBinding = new MyTupleBinding();
MyData2 theKeyData = new MyData2();
theKeyData.setLong(123456789l);
theKeyData.setDouble(new Double(12345.6789));
theKeyData.setString("My key data");
DatabaseEntry myKey = new DatabaseEntry();
try {
// Store theKeyData in the DatabaseEntry
keyBinding.objectToEntry(theKeyData, myKey);
...
// Database put and get activity omitted for clarity
...
// Retrieve the key data
theKeyData = (MyData2) keyBinding.entryToObject(myKey);
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="usingDbt.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DBEntry.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dbtJavaUsage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Reading and Writing Database Records </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Database Usage Example</td>
</tr>
</table>
</div>
</body>
</html>

540
docs/gsg/JAVA/btree.html Normal file
View File

@@ -0,0 +1,540 @@
<?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>BTree Configuration</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dbconfig.html" title="Chapter 11. Database Configuration" />
<link rel="previous" href="cachesize.html" title="Selecting the Cache Size" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">BTree Configuration</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="cachesize.html">Prev</a> </td>
<th width="60%" align="center">Chapter 11. Database Configuration</th>
<td width="20%" align="right"> </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="btree"></a>BTree Configuration</h2>
</div>
</div>
<div></div>
</div>
<p>
In going through the previous chapters in this book, you may notice that
we touch on some topics that are specific to BTree, but we do not cover
those topics in any real detail. In this section, we will discuss
configuration issues that are unique to BTree.
</p>
<p>
Specifically, in this section we describe:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Allowing duplicate records.
</p>
</li>
<li>
<p>
Setting comparator callbacks.
</p>
</li>
</ul>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="duplicateRecords"></a>Allowing Duplicate Records</h3>
</div>
</div>
<div></div>
</div>
<p>
BTree databases can contain duplicate records. One record is
considered to be a duplicate of another when both records use keys
that compare as equal to one another.
</p>
<p>
By default, keys are compared using a lexicographical comparison,
with shorter keys collating higher than longer keys.
You can override this default using the
<tt class="methodname">DatabaseConfig.setBtreeComparator()</tt>
method. See the next section for details.
</p>
<p>
By default, DB databases do not allow duplicate records. As a
result, any attempt to write a record that uses a key equal to a
previously existing record results in the previously existing record
being overwritten by the new record.
</p>
<p>
Allowing duplicate records is useful if you have a database that
contains records keyed by a commonly occurring piece of information.
It is frequently necessary to allow duplicate records for secondary
databases.
</p>
<p>
For example, suppose your primary database contained records related
to automobiles. You might in this case want to be able to find all
the automobiles in the database that are of a particular color, so
you would index on the color of the automobile. However, for any
given color there will probably be multiple automobiles. Since the
index is the secondary key, this means that multiple secondary
database records will share the same key, and so the secondary
database must support duplicate records.
</p>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="sorteddups"></a>Sorted Duplicates</h4>
</div>
</div>
<div></div>
</div>
<p>
Duplicate records can be stored in sorted or unsorted order.
You can cause DB to automatically sort your duplicate
records by
<span>
setting <tt class="methodname">DatabaseConfig.setSortedDuplicates()</tt>
to <tt class="literal">true</tt>. Note that this property must be
set prior to database creation time and it cannot be changed
afterwards.
</span>
</p>
<p>
If sorted duplicates are supported, then the
<span>
<tt class="classname">java.util.Comparator</tt> implementation
identified to
<tt class="methodname">DatabaseConfig.setDuplicateComparator()</tt>
</span>
is used to determine the location of the duplicate record in its
duplicate set. If no such function is provided, then the default
lexicographical comparison is used.
</p>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="nosorteddups"></a>Unsorted Duplicates</h4>
</div>
</div>
<div></div>
</div>
<p>
For performance reasons, BTrees should always contain sorted
records. (BTrees containing unsorted entries must potentially
spend a great deal more time locating an entry than does a BTree
that contains sorted entries). That said, DB provides support
for suppressing automatic sorting of duplicate records because it may be that
your application is inserting records that are already in a
sorted order.
</p>
<p>
That is, if the database is configured to support unsorted
duplicates, then the assumption is that your application
will manually perform the sorting. In this event,
expect to pay a significant performance penalty. Any time you
place records into the database in a sort order not know to
DB, you will pay a performance penalty
</p>
<p>
That said, this is how DB behaves when inserting records
into a database that supports non-sorted duplicates:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
If your application simply adds a duplicate record using
<span><tt class="methodname">Database.put()</tt>,</span>
then the record is inserted at the end of its sorted duplicate set.
</p>
</li>
<li>
<p>
If a cursor is used to put the duplicate record to the database,
then the new record is placed in the duplicate set according to the
actual method used to perform the put. The relevant methods
are:
</p>
<div class="itemizedlist">
<ul type="circle">
<li>
<p>
<tt class="methodname">Cursor.putAfter()</tt>
</p>
<p>
The data
is placed into the database
as a duplicate record. The key used for this operation is
the key used for the record to which the cursor currently
refers. Any key provided on the call
is therefore ignored.
</p>
<p>
The duplicate record is inserted into the database
immediately after the cursor's current position in the
database.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.putBefore()</tt>
</p>
<p>
Behaves the same as
<tt class="methodname">Cursor.putAfter()</tt>
except that the new record is inserted immediately before
the cursor's current location in the database.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.putKeyFirst()</tt>
</p>
<p>
If the key
already exists in the
database, and the database is configured to use duplicates
without sorting, then the new record is inserted as the first entry
in the appropriate duplicates list.
</p>
</li>
<li>
<p>
<tt class="methodname">Cursor.putKeyLast()</tt>
</p>
<p>
Behaves identically to
<tt class="methodname">Cursor.putKeyFirst()</tt>
except that the new duplicate record is inserted as the last
record in the duplicates list.
</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="specifyingDups"></a>Configuring a Database to Support Duplicates</h4>
</div>
</div>
<div></div>
</div>
<p>
Duplicates support can only be configured
at database creation time. You do this by specifying the appropriate
<span>
<tt class="classname">DatabaseConfig</tt> method
</span>
before the database is opened for the first time.
</p>
<p>
The
<span>methods</span>
that you can use are:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">DatabaseConfig.setUnsortedDuplicates()</tt>
</p>
<p>
The database supports non-sorted duplicate records.
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setSortedDuplicates()</tt>
</p>
<p>
The database supports sorted duplicate records.
</p>
</li>
</ul>
</div>
<p>
The following code fragment illustrates how to configure a database
to support sorted duplicate records:
</p>
<a id="java_btree_dupsort"></a>
<pre class="programlisting">package db.GettingStarted;
import java.io.FileNotFoundException;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
...
Database myDb = null;
try {
// Typical configuration settings
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setType(DatabaseType.BTREE);
myDbConfig.setAllowCreate(true);
// Configure for sorted duplicates
myDbConfig.setSortedDuplicates(true);
// Open the database
myDb = new Database("mydb.db", null, myDbConfig);
} catch(DatabaseException dbe) {
System.err.println("MyDbs: " + dbe.toString());
System.exit(-1);
} catch(FileNotFoundException fnfe) {
System.err.println("MyDbs: " + fnfe.toString());
System.exit(-1);
} </pre>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="comparators"></a>Setting Comparison Functions</h3>
</div>
</div>
<div></div>
</div>
<p>
By default, DB uses a lexicographical comparison function where
shorter records collate before longer records. For the majority of
cases, this comparison works well and you do not need to manage
it in any way.
</p>
<p>
However, in some situations your application's performance can
benefit from setting a custom comparison routine. You can do this
either for database keys, or for the data if your
database supports sorted duplicate records.
</p>
<p>
Some of the reasons why you may want to provide a custom sorting
function are:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Your database is keyed using strings and you want to provide
some sort of language-sensitive ordering to that data. Doing
so can help increase the locality of reference that allows
your database to perform at its best.
</p>
</li>
<li>
<p>
You are using a little-endian system (such as x86) and you
are using integers as your database's keys. Berkeley DB
stores keys as byte strings and little-endian integers
do not sort well when viewed as byte strings. There are
several solutions to this problem, one being to provide a
custom comparison function. See
<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_misc/faq.html" target="_top">http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_misc/faq.html</a>
for more information.
</p>
</li>
<li>
<p>
You you do not want the entire key to participate in the
comparison, for whatever reason. In
this case, you may want to provide a custom comparison
function so that only the relevant bytes are examined.
</p>
</li>
</ul>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="creatingComparisonFunctions"></a>
<span>Creating Java Comparators</span>
</h4>
</div>
</div>
<div></div>
</div>
<p>
You set a BTree's key
<span>
comparator
</span>
using
<span><tt class="methodname">DatabaseConfig.setBtreeComparator()</tt>.</span>
You can also set a BTree's duplicate data comparison function using
<span><tt class="methodname">DatabaseConfig.setDuplicateComparator()</tt>.</span>
</p>
<p>
<span>
If
</span>
the database already exists when it is opened, the
<span>
comparator
</span>
provided to these methods must be the same as
that historically used to create the database or corruption can
occur.
</p>
<p>
You override the default comparison function by providing a Java
<tt class="classname">Comparator</tt> class to the database.
The Java <tt class="classname">Comparator</tt> interface requires you to implement the
<tt class="methodname">Comparator.compare()</tt> method
(see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html" target="_top">http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html</a> for details).
</p>
<p>
DB hands your <tt class="methodname">Comparator.compare()</tt> method
the <tt class="literal">byte</tt> arrays that you stored in the database. If
you know how your data is organized in the <tt class="literal">byte</tt>
array, then you can write a comparison routine that directly examines
the contents of the arrays. Otherwise, you have to reconstruct your
original objects, and then perform the comparison.
</p>
<p>
For example, suppose you want to perform unicode lexical comparisons
instead of UTF-8 byte-by-byte comparisons. Then you could provide a
comparator that uses <tt class="methodname">String.compareTo()</tt>,
which performs a Unicode comparison of two strings (note that for
single-byte roman characters, Unicode comparison and UTF-8
byte-by-byte comparisons are identical this is something you
would only want to do if you were using multibyte unicode characters
with DB). In this case, your comparator would look like the
following:
</p>
<a id="java_btree1"></a>
<pre class="programlisting">package db.GettingStarted;
import java.util.Comparator;
public class MyDataComparator implements Comparator {
public MyDataComparator() {}
public int compare(Object d1, Object d2) {
byte[] b1 = (byte[])d1;
byte[] b2 = (byte[])d2;
String s1 = new String(b1);
String s2 = new String(b2);
return s1.compareTo(s2);
}
} </pre>
<p>
To use this comparator:
</p>
<a id="java_btree2"></a>
<pre class="programlisting">package db.GettingStarted;
import java.io.FileNotFoundException;
import java.util.Comparator;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
...
Database myDatabase = null;
try {
// Get the database configuration object
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(true);
// Set the duplicate comparator class
MyDataComparator mdc = new MyDataComparator();
myDbConfig.setDuplicateComparator(mdc);
// Open the database that you will use to store your data
myDbConfig.setSortedDuplicates(true);
myDatabase = new Database("myDb", null, myDbConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
}</pre>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="cachesize.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dbconfig.html">Up</a>
</td>
<td width="40%" align="right"> </td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Selecting the Cache Size </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> </td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,98 @@
<?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>Selecting the Cache Size</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dbconfig.html" title="Chapter 11. Database Configuration" />
<link rel="previous" href="dbconfig.html" title="Chapter 11. Database Configuration" />
<link rel="next" href="btree.html" title="BTree Configuration" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Selecting the Cache Size</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dbconfig.html">Prev</a> </td>
<th width="60%" align="center">Chapter 11. Database Configuration</th>
<td width="20%" align="right"> <a accesskey="n" href="btree.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="cachesize"></a>Selecting the Cache Size</h2>
</div>
</div>
<div></div>
</div>
<p>
Cache size is important to your application because if it is set to too
small of a value, your application's performance will suffer from too
much disk I/O. On the other hand, if your cache is too large, then your
application will use more memory than it actually needs.
Moreover, if your application uses too much memory, then on most
operating systems this can result in your application being swapped out
of memory, resulting in extremely poor performance.
</p>
<p>
You select your cache size using either
<span>
<tt class="methodname">DatabaseConfig.setCacheSize()</tt>, or
<tt class="methodname">EnvironmentConfig.setCacheSize()</tt>,
</span>
depending on whether you are using a database environment or not. You
cache size must be a power of 2, but it is otherwise limited only by
available memory and performance considerations.
</p>
<p>
Selecting a cache size is something of an art, but fortunately you
can change it any time, so it can be easily tuned to your
application's changing data requirements. The best way to
determine how large your cache needs to be is to put your
application into a production environment and watch to see how much
disk I/O is occurring. If your application is going to disk quite a
lot to retrieve database records, then you should increase the size
of your cache (provided that you have enough memory to do so).
</p>
<p>
You can use the <tt class="literal">db_stat</tt> command line utility with the
<tt class="literal">-m</tt> option to gauge the effectiveness of your cache.
In particular, the number of pages found in the cache is shown, along
with a percentage value. The closer to 100% that you can get, the
better. If this value drops too low, and you are experiencing
performance problems, then you should consider increasing the size of
your cache, assuming you have memory to support it.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dbconfig.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dbconfig.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="btree.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 11. Database Configuration </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> BTree Configuration</td>
</tr>
</table>
</div>
</body>
</html>

168
docs/gsg/JAVA/concepts.html Normal file
View File

@@ -0,0 +1,168 @@
<?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>Berkeley DB Concepts</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="next" href="accessmethods.html" title="Access Methods" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Berkeley DB Concepts</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="introduction.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="accessmethods.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="concepts"></a>Berkeley DB Concepts</h2>
</div>
</div>
<div></div>
</div>
<p>
Before continuing, it is useful to describe some of the larger concepts
that you will encounter when building a DB application.
</p>
<p>
Conceptually, DB databases contain <span class="emphasis"><em>records</em></span>.
Logically each record represents a single entry in the database.
Each such record contains two pieces of information: a key and a data.
This manual will on occasion describe a <span class="emphasis"><em>a record's
key</em></span> or a <span class="emphasis"><em>record's data</em></span> when it is
necessary to speak to one or the other portion of a database
record.
</p>
<p>
Because of the key/data pairing used for DB databases, they are
sometimes thought of as a two-column table. However, data (and
sometimes keys, depending on the access method) can hold arbitrarily
complex data. Frequently, C structures and other such mechanisms are
stored in the record. This effectively turns a 2-column table
into a table with <span class="emphasis"><em>n</em></span> columns, where
<span class="emphasis"><em>n-1</em></span> of those columns are provided by the structure's
fields.
</p>
<p>
Note that a DB database is very much like a table in a relational
database system in that most DB applications use more than one
database (just as most relational databases use more than one table).
</p>
<p>
Unlike relational systems, however, a DB database contains a single
collection of records organized according to a given access method
(BTree, Queue, Hash, and so forth). In a relational database system,
the underlying access method is generally hidden from you.
</p>
<p>
In any case, frequently DB
applications are designed so that a single database stores a specific
type of data (just as in a relational database system, a single table
holds entries containing a specific set of fields). Because most applications
are required to manage multiple kinds of data, a DB application will
often use multiple databases.
</p>
<p>
For example, consider an accounting application. This kind of an
application may manage data based on bank accounts, checking
accounts, stocks, bonds, loans, and so forth. An accounting application
will also have to manage information about people, banking institutions,
customer accounts, and so on. In a traditional relational database, all
of these different kinds of information would be stored and managed
using a (probably very) complex series of tables. In a DB
application, all of this information would instead be divided out and
managed using multiple databases.
</p>
<p>
DB applications can efficiently use multiple databases using an
optional mechanism called an <span class="emphasis"><em>environment</em></span>.
For more information, see <a href="environments.html">Environments</a>.
</p>
<p>
You interact with most DB APIs using special structures that
contain pointers to functions. These callbacks are
called <span class="emphasis"><em>methods</em></span> because they look so much like a
method on a C++ class. The variable that you use to access these
methods is often referred to as a
<span class="emphasis"><em>handle</em></span>. For example, to use a database you will
obtain a handle to that database.
</p>
<p>
Retrieving a record from a database is sometimes called
<span class="emphasis"><em>getting the record</em></span> because the method that you use
to retrieve the records is called <tt class="methodname">get()</tt>.
Similarly, storing database records is sometimes called
<span class="emphasis"><em>putting the record</em></span> because you use the
<tt class="methodname">put()</tt> method to do this.
</p>
<p>
When you store, or put, a record to a database using its handle, the
record is stored according to whatever sort order is in use by the
database. Sorting is mostly performed based on the key, but sometimes
the data is considered too. If you put a record using a key that already
exists in the database, then the existing record is replaced with the
new data. However, if the database supports
duplicate records (that is, records with identical keys but
different data), then that new record is stored as a duplicate record and
any existing records are not overwritten.
</p>
<p>
If a database supports duplicate records, then you can use a database
handle to retrieve only the first record in a set of duplicate records.
</p>
<p>
In addition to using a database handle, you can also read and write data using a
special mechanism called a <span class="emphasis"><em>cursor</em></span>. Cursors are
essentially iterators that you can use to walk over the records in a
database. You can use cursors to iterate over a database from the first
record to the last, and from the last to the first. You can also use
cursors to seek to a record. In the event that a database supports
duplicate records, cursors are the only way you can access all the
records in a set of duplicates.
</p>
<p>
Finally, DB provides a special kind of a database called a
<span class="emphasis"><em>secondary database</em></span>. Secondary databases serve as an
index into normal databases (called primary database to distinguish them
from secondaries). Secondary databases are interesting because DB
records can hold complex data types, but seeking to a given record is
performed only based on that record's key. If you wanted to be able to
seek to a record based on some piece of information that is not the key,
then you enable this through the use of secondary databases.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="introduction.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="accessmethods.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 1. Introduction to Berkeley DB  </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Access Methods</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,102 @@
<?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>Exception Handling</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="databaseLimits.html" title="Database Limits and Portability" />
<link rel="next" href="returns.html" title="Error Returns" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Exception Handling</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="databaseLimits.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="returns.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="coreExceptions"></a>Exception Handling</h2>
</div>
</div>
<div></div>
</div>
<p>
Before continuing, it is useful to spend a few moments on exception
handling in DB with the
<span>java</span>.
</p>
<p>
<span>Most</span>
DB methods throw
<tt class="classname">DatabaseException</tt>
in the event of a serious error.
<span>
So your DB code must either catch this exception or declare it
to be throwable. Be aware that <tt class="classname">DatabaseException</tt> extends
<tt class="classname">java.lang.Exception</tt>. For example:
</span>
</p>
<a id="java_intro1"></a>
<pre class="programlisting">import com.sleepycat.db.DatabaseException;
...
try
{
// DB and other code goes here
}
catch(DatabaseException e)
{
// DB error handling goes here
} </pre>
<p>
You can obtain the DB error number for a
<tt class="classname">DatabaseException</tt>
by using
<span>
<tt class="methodname">DatabaseException.getErrno()</tt>.
You can also obtain any error message associated with that error
using <tt class="methodname">DatabaseException.getMessage()</tt>.
</span>
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="databaseLimits.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="returns.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Database Limits and Portability </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Error Returns</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,103 @@
<?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>Closing Databases</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DB.html" title="Chapter 7. Databases" />
<link rel="previous" href="DB.html" title="Chapter 7. Databases" />
<link rel="next" href="DBConfig.html" title="Database Properties" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Closing Databases</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="DB.html">Prev</a> </td>
<th width="60%" align="center">Chapter 7. Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="DBConfig.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="coredbclose"></a>Closing Databases</h2>
</div>
</div>
<div></div>
</div>
<p>
Once you are done using the database, you must close it. You use the
method to do this.
</p>
<p>
Closing a database causes it to become unusable until it is opened
again. Note that you should make sure that any open cursors are closed
before closing your database. Active cursors during a database
close can cause unexpected results, especially if any of those cursors are
writing to the database. You should always make sure that all your
database accesses have completed before closing your database.
</p>
<p>
Cursors are described in <a href="Cursors.html">Using Cursors</a> later in this manual.
</p>
<p>
Be aware that when you close the last open handle
for a database, then by default its cache is flushed to disk.
This means that any information that has
been modified in the cache is guaranteed to be written to disk when the
last handle is closed. You can manually perform this operation using
the
<tt class="methodname">Database.sync()</tt>
method, but for normal shutdown operations it is not necessary.
For more information about syncing your cache, see
<a href="usingDbt.html#datapersist">Data Persistence</a>.
</p>
<p>The following code fragment illustrates a database close:</p>
<a id="java_db2"></a>
<pre class="programlisting">import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Database;
...
try {
if (myDatabase != null) {
myDatabase.close();
}
} catch (DatabaseException dbe) {
// Exception handling goes here
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="DB.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DB.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="DBConfig.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 7. Databases </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Database Properties</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,278 @@
<?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>Cursor Example</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="Cursors.html" title="Chapter 9. Using Cursors" />
<link rel="previous" href="ReplacingEntryWCursor.html" title="Replacing Records Using Cursors" />
<link rel="next" href="indexes.html" title="Chapter 10. Secondary Databases" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Cursor Example</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="ReplacingEntryWCursor.html">Prev</a> </td>
<th width="60%" align="center">Chapter 9. Using Cursors</th>
<td width="20%" align="right"> <a accesskey="n" href="indexes.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="cursorJavaUsage"></a>Cursor Example</h2>
</div>
</div>
<div></div>
</div>
<p>In <a href="dbtJavaUsage.html">Database Usage Example</a> we wrote an
application that loaded two <tt class="classname">Database</tt> objects with vendor
and inventory information. In this example, we will use those databases to
display all of the items in the inventory database. As a part of showing
any given inventory item, we will look up the vendor who can provide the
item and show the vendor's contact information.</p>
<p>To do this, we create the <tt class="classname">ExampleDatabaseRead</tt>
application. This application reads and displays all inventory records by:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Opening the inventory, vendor, and
class catalog <tt class="classname">Database</tt> objects. We do this using the
<tt class="classname">MyDbs</tt> class. See <a href="dbtJavaUsage.html#dbsStoredClass">Stored Class Catalog Management with MyDbs</a>
for a description of this class.</p>
</li>
<li>
<p>Obtaining a cursor from the inventory <tt class="classname">Database</tt>.</p>
</li>
<li>
<p>Steps through the <tt class="classname">Database</tt>, displaying
each record as it goes.</p>
</li>
<li>
<p>To display the Inventory record, the custom tuple binding that
we created in <a href="dbtJavaUsage.html#InventoryJavaBinding">InventoryBinding.java</a> is used.</p>
</li>
<li>
<p><tt class="methodname">Database.get()</tt> is used to obtain the vendor that corresponds to
the inventory item.</p>
</li>
<li>
<p>A serial binding is used to convert the
<tt class="classname">DatabaseEntry</tt> returned
by the <tt class="methodname">get()</tt> to a Vendor object.</p>
</li>
<li>
<p>The contents of the Vendor object are displayed.</p>
</li>
</ol>
</div>
<p>We implemented the <tt class="classname">Vendor</tt> class in <a href="dbtJavaUsage.html#vendorjava">Vendor.java</a>. We implemented the
<tt class="classname">Inventory</tt> class in <a href="dbtJavaUsage.html#inventoryjava">Inventory.java</a>.</p>
<p>The full implementation of <tt class="classname">ExampleDatabaseRead</tt>
can be found in:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
<div class="example">
<a id="EDR"></a>
<p class="title">
<b>Example 9.1 ExampleDatabaseRead.java</b>
</p>
<p>To begin, we import the necessary classes:</p>
<a id="java_cursor10"></a>
<pre class="programlisting">// file ExampleDatabaseRead.java
package db.GettingStarted;
import java.io.File;
import java.io.IOException;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;</pre>
<p>Next we declare our class and set up some global variables. Note a
<tt class="classname">MyDbs</tt> object is instantiated here. We can do
this because its constructor never throws an exception. See <a href="CoreJavaUsage.html">Database Example</a> for its implementation
details.</p>
<a id="java_cursor11"></a>
<pre class="programlisting">public class ExampleDatabaseRead {
private static String myDbsPath = "./";
// Encapsulates the database environment and databases.
private static MyDbs myDbs = new MyDbs();
private static TupleBinding inventoryBinding;
private static EntryBinding vendorBinding; </pre>
<p>
Next we create the <tt class="methodname">ExampleDatabaseRead.usage()</tt> and
<tt class="methodname">ExampleDatabaseRead.main()</tt> methods.
We perform almost all of our exception handling from <tt class="methodname">ExampleDatabaseRead.main()</tt>, and so we
must catch <tt class="classname">DatabaseException</tt> because the <tt class="literal">com.sleepycat.db.*</tt>
APIs throw them.
</p>
<a id="java_cursor12"></a>
<pre class="programlisting"> private static void usage() {
System.out.println("ExampleDatabaseRead [-h &lt;env directory&gt;]" +
"[-s &lt;item to locate&gt;]");
System.exit(-1);
}
public static void main(String args[]) {
ExampleDatabaseRead edr = new ExampleDatabaseRead();
try {
edr.run(args);
} catch (DatabaseException dbe) {
System.err.println("ExampleDatabaseRead: " + dbe.toString());
dbe.printStackTrace();
} finally {
myDbs.close();
}
System.out.println("All done.");
}</pre>
<p>In <tt class="methodname">ExampleDatabaseRead.run()</tt>, we call <tt class="methodname">MyDbs.setup()</tt> to
open our databases. Then we create the bindings that we need for using our data objects with
<tt class="classname">DatabaseEntry</tt> objects.
</p>
<a id="java_cursor13"></a>
<pre class="programlisting"> private void run(String args[])
throws DatabaseException {
// Parse the arguments list
parseArgs(args);
myDbs.setup(myDbsPath);
// Setup our bindings.
inventoryBinding = new InventoryBinding();
vendorBinding =
new SerialBinding(myDbs.getClassCatalog(),
Vendor.class);
showAllInventory();
}</pre>
<p>Now we write the loop that displays the <tt class="classname">Inventory</tt>
records. We do this by opening a cursor on the inventory database and
iterating over all its contents, displaying each as we go.</p>
<a id="java_cursor14"></a>
<pre class="programlisting"> private void showAllInventory()
throws DatabaseException {
// Get a cursor
Cursor cursor = myDbs.getInventoryDB().openCursor(null, null);
// DatabaseEntry objects used for reading records
DatabaseEntry foundKey = new DatabaseEntry();
DatabaseEntry foundData = new DatabaseEntry();
try { // always want to make sure the cursor gets closed
while (cursor.getNext(foundKey, foundData,
LockMode.DEFAULT) == OperationStatus.SUCCESS) {
Inventory theInventory =
(Inventory)inventoryBinding.entryToObject(foundData);
displayInventoryRecord(foundKey, theInventory);
}
} catch (Exception e) {
System.err.println("Error on inventory cursor:");
System.err.println(e.toString());
e.printStackTrace();
} finally {
cursor.close();
}
} </pre>
<p>We use <tt class="methodname">ExampleDatabaseRead.displayInventoryRecord()</tt>
to actually show the record. This
method first displays all the relevant information from the retrieved
Inventory object. It then uses the vendor database to retrieve and
display the vendor. Because the vendor database is keyed by vendor name,
and because each inventory object contains this key, it is trivial to
retrieve the appropriate vendor record.</p>
<a id="java_cursor15"></a>
<pre class="programlisting"> private void displayInventoryRecord(DatabaseEntry theKey,
Inventory theInventory)
throws DatabaseException {
String theSKU = new String(theKey.getData(), "UTF-8");
System.out.println(theSKU + ":");
System.out.println("\t " + theInventory.getItemName());
System.out.println("\t " + theInventory.getCategory());
System.out.println("\t " + theInventory.getVendor());
System.out.println("\t\tNumber in stock: " +
theInventory.getVendorInventory());
System.out.println("\t\tPrice per unit: " +
theInventory.getVendorPrice());
System.out.println("\t\tContact: ");
DatabaseEntry searchKey = null;
try {
searchKey =
new DatabaseEntry(theInventory.getVendor().getBytes("UTF-8"));
} catch (IOException willNeverOccur) {}
DatabaseEntry foundVendor = new DatabaseEntry();
if (myDbs.getVendorDB().get(null, searchKey, foundVendor,
LockMode.DEFAULT) != OperationStatus.SUCCESS) {
System.out.println("Could not find vendor: " +
theInventory.getVendor() + ".");
System.exit(-1);
} else {
Vendor theVendor =
(Vendor)vendorBinding.entryToObject(foundVendor);
System.out.println("\t\t " + theVendor.getAddress());
System.out.println("\t\t " + theVendor.getCity() + ", " +
theVendor.getState() + " " + theVendor.getZipcode());
System.out.println("\t\t Business Phone: " +
theVendor.getBusinessPhoneNumber());
System.out.println("\t\t Sales Rep: " +
theVendor.getRepName());
System.out.println("\t\t " +
theVendor.getRepPhoneNumber());
}
}</pre>
<p>The remainder of this application provides a utility method used
to parse the command line options. From the perspective of this
document, this is relatively uninteresting. You can see how this is
implemented by looking at:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="ReplacingEntryWCursor.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="Cursors.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="indexes.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Replacing Records Using Cursors </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 10. Secondary Databases</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<?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>DataAccessor.class</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl_example.html" title="Chapter 6. A DPL Example" />
<link rel="previous" href="mydbenv-persist.html" title="MyDbEnv" />
<link rel="next" href="dpl_exampledatabaseput.html" title="ExampleDatabasePut.class" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">DataAccessor.class</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="mydbenv-persist.html">Prev</a> </td>
<th width="60%" align="center">Chapter 6. A DPL Example</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl_exampledatabaseput.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="dataaccessorclass"></a>DataAccessor.class</h2>
</div>
</div>
<div></div>
</div>
<p>
Now that we have implemented our data classes,
we can write a class that will provide
convenient access to our primary and
secondary indexes.
Note that like our data classes, this class is shared by both our
example programs.
</p>
<p>
If you compare this class against our
<tt class="classname">Vendor</tt> and
<tt class="classname">Inventory</tt>
class implementations, you will see that the
primary and secondary indices declared there are
referenced by this class.
</p>
<p>
See <a href="dpl_example.html#vendorclass">Vendor.class</a>
and
<a href="inventoryclass.html">Inventory.class</a>
for those implementations.
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;
public class DataAccessor {
// Open the indices
public DataAccessor(EntityStore store)
throws DatabaseException {
// Primary key for Inventory classes
inventoryBySku = store.getPrimaryIndex(
String.class, Inventory.class);
// Secondary key for Inventory classes
// Last field in the getSecondaryIndex() method must be
// the name of a class member; in this case, an Inventory.class
// data member.
inventoryByName = store.getSecondaryIndex(
inventoryBySku, String.class, "itemName");
// Primary key for Vendor class
vendorByName = store.getPrimaryIndex(
String.class, Vendor.class);
}
// Inventory Accessors
PrimaryIndex&lt;String,Inventory&gt; inventoryBySku;
SecondaryIndex&lt;String,String,Inventory&gt; inventoryByName;
// Vendor Accessors
PrimaryIndex&lt;String,Vendor&gt; vendorByName;
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="mydbenv-persist.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl_example.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl_exampledatabaseput.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">MyDbEnv </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> ExampleDatabasePut.class</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,81 @@
<?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>Database Limits and Portability</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="accessmethods.html" title="Access Methods" />
<link rel="next" href="coreExceptions.html" title="Exception Handling" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Database Limits and Portability</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="accessmethods.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="coreExceptions.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="databaseLimits"></a>Database Limits and Portability</h2>
</div>
</div>
<div></div>
</div>
<p>
Berkeley DB provides support for managing everything from very small
databases that fit entirely in memory, to extremely large databases
holding millions of records and terabytes of data. DB databases can
store up to 256 terabytes of data. Individual record keys or record
data can store up to 4 gigabytes of data.
</p>
<p>
DB's databases store data in a binary format that is portable across
platforms, even of differing endian-ness. Be aware, however, that
portability aside, some performance issues can crop up in the event that
you are using little endian architecture. See <a href="btree.html#comparators">Setting Comparison Functions</a>
for more information.
</p>
<p>
Also, DB's databases and data structures are designed for concurrent
access — they are thread-safe, and they share well across multiple
processes. That said, in order to allow multiple processes to share
databases and the cache, DB makes use of mechanisms that do not work
well on network-shared drives (NFS or Windows networks shares, for
example). For this reason, you cannot place your DB databases and
environments on network-mounted drives.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="accessmethods.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="coreExceptions.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Access Methods </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Exception Handling</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,147 @@
<?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>Error Reporting Functions</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DB.html" title="Chapter 7. Databases" />
<link rel="previous" href="DBAdmin.html" title="Administrative Methods" />
<link rel="next" href="CoreEnvUsage.html" title="Managing Databases in Environments" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Error Reporting Functions</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="DBAdmin.html">Prev</a> </td>
<th width="60%" align="center">Chapter 7. Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="CoreEnvUsage.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="dbErrorReporting"></a>Error Reporting Functions</h2>
</div>
</div>
<div></div>
</div>
<p>
To simplify error reporting and handling, the
<span><tt class="classname">DatabaseConfig</tt> class</span>
offers several useful methods.
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">DatabaseConfig.setErrorStream()</tt>
</p>
<p>
Sets the
<span>Java <tt class="classname">OutputStream</tt></span>
to be used for displaying error messages issued by the DB library.
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setMessageHandler()</tt>
</p>
<p>
Defines the message handler that is called when an error message is
issued by DB. The error prefix and message are passed to
this callback. It is up to the application to display this
information correctly.
</p>
<p>
Note that the message handler must be an implementation of the
<tt class="classname">com.sleepycat.db.MessageHandler</tt>
interface.
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setErrorPrefix()</tt>
</p>
<p>
Sets the prefix used for any error messages issued by the
DB library.
</p>
</li>
</ul>
</div>
<p>
For example, to send all your error messages to a particular message
handler, first implement the handler:
</p>
<a id="java_db10"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Environment;
import com.sleepycat.db.MessageHandler;
public class MyMessageHandler implements MessageHandler {
// Our constructor does nothing
public MyMessageHandler() {}
public void message(Environment dbenv, String message)
{
// Put your special message handling code here
}
}</pre>
<p>
And then set up your database to use the message handler by identifying
it on the database's <tt class="classname">DatabaseConfig</tt> object:
</p>
<a id="java_db11"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseConfig;
...
DatabaseConfig myDbConfig = new DatabaseConfig();
MyMessageHandler mmh = new MyMessageHandler();
myDbConfig.setMessageHandler(mmh); </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="DBAdmin.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DB.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="CoreEnvUsage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Administrative Methods </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Managing Databases in Environments</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="ISO-8859-1" 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=ISO-8859-1" />
<title>Database Properties</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DB.html" title="Chapter<65>2.<2E>Databases" />
<link rel="previous" href="coredbclose.html" title="Closing Databases" />
<link rel="next" href="DBAdmin.html" title="Administrative Methods" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Database Properties</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="coredbclose.html">Prev</a><EFBFBD></td>
<th width="60%" align="center">Chapter<EFBFBD>2.<2E>Databases</th>
<td width="20%" align="right"><EFBFBD><a accesskey="n" href="DBAdmin.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="db_config"></a>Database Properties</h2>
</div>
</div>
<div></div>
</div>
<p>You can set database properties using the <tt class="classname">DatabaseConfig</tt>
class. For each of the properties that you can set, there is a
corresponding getter method. Also, you can always retrieve the
<tt class="classname">DatabaseConfig</tt> object used by your database using
the <tt class="methodname">Database.getConfig()</tt> method.</p>
<p>
There are a large number of properties that you can set using this
class (see the javadoc for a complete listing). From the perspective of
this manual, some of the more interesting properties are:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">DatabaseConfig.setAllowCreate()</tt>
</p>
<p>If <tt class="literal">true</tt>, the database is created when it is
opened. If false, the database open fails if the database does not
exist. This property has no meaning if the database currently exists.
Default is <tt class="literal">false</tt>.</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setBtreeComparator()</tt>
</p>
<p>Sets the class that is used to compare the keys found on two
database records. This class is used to determine the sort order for
two records in the database. For more information, see
<span><a href="btree.html#comparators">Setting Comparison Functions</a>.</span>
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setDuplicateComparator()</tt>
</p>
<p>
Sets the class that is used to compare two duplicate records in
the database. For more information, see
<span><a href="btree.html#comparators">Setting Comparison Functions</a>.</span>
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setSortedDuplicates()</tt>
</p>
<p>If <tt class="literal">true</tt>, duplicate records are allowed in the
database. If this value is <tt class="literal">false</tt>, then putting a duplicate record into the database
results in the replacement of the old record with the new record.
Note that this property can be set only at database creation time. Default is <tt class="literal">false</tt>.
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setExclusiveCreate()</tt>
</p>
<p>If <tt class="literal">true</tt>, the database open fails if the
database currently exists. That is, the open must result in the
creation of a new database. Default is <tt class="literal">false</tt>.</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setReadOnly()</tt>
</p>
<p>If true, the database is opened for read activities only.
Default is <tt class="literal">false</tt>.</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setTruncate()</tt>
</p>
<p>If true, the database is truncated; that is, it is emptied of all
content.
</p>
</li>
<li>
<p>
<tt class="methodname">DatabaseConfig.setType()</tt>
</p>
<p>Identifies the type of database that you want to create. This
manual will exclusively use <tt class="literal">DatabaseType.BTREE</tt>.
</p>
</li>
</ul>
</div>
<p>
In addition to these, there are also methods that allow you to
control the IO stream used for error reporting purposes.
These are described later in this manual.
</p>
<p>For example:</p>
<a id="java_db3"></a>
<pre class="programlisting">package com.sleepycat.examples.db.GettingStarted;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
import java.io.FileNotFoundException;
...
Database myDatabase = null;
try {
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
dbConfig.setSortedDuplicates(true);
dbConfig.setType(DatabaseType.BTREE);
myDatabase = new Database("sampleDatabase.db",
null,
dbConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here.
} catch (FileNotFoundException fnfe) {
// Exception handling goes here
}</pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="coredbclose.html">Prev</a><EFBFBD></td>
<td width="20%" align="center">
<a accesskey="u" href="DB.html">Up</a>
</td>
<td width="40%" align="right"><EFBFBD><a accesskey="n" href="DBAdmin.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Closing Databases<65></td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"><EFBFBD>Administrative Methods</td>
</tr>
</table>
</div>
</body>
</html>

398
docs/gsg/JAVA/dbconfig.html Normal file
View File

@@ -0,0 +1,398 @@
<?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>Chapter 11. Database Configuration</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="baseapi.html" title="Part II. Programming with the Base API" />
<link rel="previous" href="javaindexusage.html" title="Secondary Database Example" />
<link rel="next" href="cachesize.html" title="Selecting the Cache Size" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 11. Database Configuration</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="javaindexusage.html">Prev</a> </td>
<th width="60%" align="center">Part II. Programming with the Base API</th>
<td width="20%" align="right"> <a accesskey="n" href="cachesize.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="dbconfig"></a>Chapter 11. Database Configuration</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="dbconfig.html#pagesize">Setting the Page Size</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="dbconfig.html#overflowpages">Overflow Pages</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#Locking">Locking</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#IOEfficiency">IO Efficiency</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#pagesizeAdvice">Page Sizing Advice</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="cachesize.html">Selecting the Cache Size</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="btree.html">BTree Configuration</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="btree.html#duplicateRecords">Allowing Duplicate Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="btree.html#comparators">Setting Comparison Functions</a>
</span>
</dt>
</dl>
</dd>
</dl>
</div>
<p>
This chapter describes some of the database and cache configuration issues
that you need to consider when building your DB database.
In most cases, there is very little that you need to do in terms of
managing your databases. However, there are configuration issues that you
need to be concerned with, and these are largely dependent on the access
method that you are choosing for your database.
</p>
<p>
The examples and descriptions throughout this document have mostly focused
on the BTree access method. This is because the majority of DB
applications use BTree. For this reason, where configuration issues are
dependent on the type of access method in use, this chapter will focus on
BTree only. For configuration descriptions surrounding the other access
methods, see the <i class="citetitle">Berkeley DB Programmer's Reference Guide</i>.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="pagesize"></a>Setting the Page Size</h2>
</div>
</div>
<div></div>
</div>
<p>
Internally, DB stores database entries on pages. Page sizes are
important because they can affect your application's performance.
</p>
<p>
DB pages can be between 512 bytes and 64K bytes in size. The size
that you select must be a power of 2. You set your database's
page size using
<span><tt class="methodname">DatabaseConfig.setPageSize()</tt>.</span>
</p>
<p>
Note that a database's page size can only be selected at database
creation time.
</p>
<p>
When selecting a page size, you should consider the following issues:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Overflow pages.
</p>
</li>
<li>
<p>
Locking
</p>
</li>
<li>
<p>
Disk I/O.
</p>
</li>
</ul>
</div>
<p>
These topics are discussed next.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="overflowpages"></a>Overflow Pages</h3>
</div>
</div>
<div></div>
</div>
<p>
Overflow pages are used to hold a key or data item
that cannot fit on a single page. You do not have to do anything to
cause overflow pages to be created, other than to store data that is
too large for your database's page size. Also, the only way you can
prevent overflow pages from being created is to be sure to select a
page size that is large enough to hold your database entries.
</p>
<p>
Because overflow pages exist outside of the normal database
structure, their use is expensive from a performance
perspective. If you select too small of a page size, then your
database will be forced to use an excessive number of overflow
pages. This will significantly harm your application's performance.
</p>
<p>
For this reason, you want to select a page size that is at
least large enough to hold multiple entries given the expected
average size of your database entries. In BTree's case, for best
results select a page size that can hold at least 4 such entries.
</p>
<p>
You can see how many overflow pages your database is using by
<span>
obtaining a <tt class="classname">DatabaseStats</tt> object using
the <tt class="methodname">Database.getStats()</tt> method,
</span>
or by examining your database using the
<tt class="literal">db_stat</tt> command line utility.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="Locking"></a>Locking</h3>
</div>
</div>
<div></div>
</div>
<p>
Locking and multi-threaded access to DB databases is built into
the product. However, in order to enable the locking subsystem and
in order to provide efficient sharing of the cache between
databases, you must use an <span class="emphasis"><em>environment</em></span>.
Environments and multi-threaded access are not fully described
in this manual (see the Berkeley DB Programmer's Reference Manual for
information), however, we provide some information on sizing your
pages in a multi-threaded/multi-process environment in the interest
of providing a complete discussion on the topic.
</p>
<p>
If your application is multi-threaded, or if your databases are
accessed by more than one process at a time, then page size can
influence your application's performance. The reason why is that
for most access methods (Queue is the exception), DB implements
page-level locking. This means that the finest locking granularity
is at the page, not at the record.
</p>
<p>
In most cases, database pages contain multiple database
records. Further, in order to provide safe access to multiple
threads or processes, DB performs locking on pages as entries on
those pages are read or written.
</p>
<p>
As the size of your page increases relative to the size of your
database entries, the number of entries that are held on any given
page also increase. The result is that the chances of two or more
readers and/or writers wanting to access entries on any given page
also increases.
</p>
<p>
When two or more threads and/or processes want to manage data on a
page, lock contention occurs. Lock contention is resolved by one
thread (or process) waiting for another thread to give up its lock.
It is this waiting activity that is harmful to your application's
performance.
</p>
<p>
It is possible to select a page size that is so large that your
application will spend excessive, and noticeable, amounts of time
resolving lock contention. Note that this scenario is particularly
likely to occur as the amount of concurrency built into your
application increases.
</p>
<p>
Oh the other hand, if you select too small of a page size, then that
that will only make your tree deeper, which can also cause
performance penalties. The trick, therefore, is to select a
reasonable page size (one that will hold a sizeable number of
records) and then reduce the page size if you notice lock
contention.
</p>
<p>
You can examine the number of lock conflicts and deadlocks occurring
in your application by examining your database environment lock
statistics. Either use the
method, or use the <tt class="literal">db_stat</tt> command line utility.
The number of unavailable locks that your application waited for is
held in the lock statistic's <tt class="literal">st_lock_wait</tt> field.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="IOEfficiency"></a>IO Efficiency</h3>
</div>
</div>
<div></div>
</div>
<p>
Page size can affect how efficient DB is at moving data to and
from disk. For some applications, especially those for which the
in-memory cache can not be large enough to hold the entire working
dataset, IO efficiency can significantly impact application performance.
</p>
<p>
Most operating systems use an internal block size to determine how much
data to move to and from disk for a single I/O operation. This block
size is usually equal to the filesystem's block size. For optimal
disk I/O efficiency, you should select a database page size that is
equal to the operating system's I/O block size.
</p>
<p>
Essentially, DB performs data transfers based on the database
page size. That is, it moves data to and from disk a page at a time.
For this reason, if the page size does not match the I/O block size,
then the operating system can introduce inefficiencies in how it
responds to DB's I/O requests.
</p>
<p>
For example, suppose your page size is smaller than your operating
system block size. In this case, when DB writes a page to disk
it is writing just a portion of a logical filesystem page. Any time
any application writes just a portion of a logical filesystem page, the
operating system brings in the real filesystem page, over writes
the portion of the page not written by the application, then writes
the filesystem page back to disk. The net result is significantly
more disk I/O than if the application had simply selected a page
size that was equal to the underlying filesystem block size.
</p>
<p>
Alternatively, if you select a page size that is larger than the
underlying filesystem block size, then the operating system may have
to read more data than is necessary to fulfill a read request.
Further, on some operating systems, requesting a single database
page may result in the operating system reading enough filesystem
blocks to satisfy the operating system's criteria for read-ahead. In
this case, the operating system will be reading significantly more
data from disk than is actually required to fulfill DB's read
request.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
While transactions are not discussed in this manual, a page size
other than your filesystem's block size can affect transactional
guarantees. The reason why is that page sizes larger than the
filesystem's block size causes DB to write pages in block
size increments. As a result, it is possible for a partial page
to be written as the result of a transactional commit. For more
information, see <a href="http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/reclimit.html" target="_top">http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/reclimit.html</a>.
</p>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="pagesizeAdvice"></a>Page Sizing Advice</h3>
</div>
</div>
<div></div>
</div>
<p>
Page sizing can be confusing at first, so here are some general
guidelines that you can use to select your page size.
</p>
<p>
In general, and given no other considerations, a page size that is equal
to your filesystem block size is the ideal situation.
</p>
<p>
If your data is designed such that 4 database entries cannot fit on a
single page (assuming BTree), then grow your page size to accommodate
your data. Once you've abandoned matching your filesystem's block
size, the general rule is that larger page sizes are better.
</p>
<p>
The exception to this rule is if you have a great deal of
concurrency occurring in your application. In this case, the closer
you can match your page size to the ideal size needed for your
application's data, the better. Doing so will allow you to avoid
unnecessary contention for page locks.
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="javaindexusage.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="baseapi.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="cachesize.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Secondary Database Example </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Selecting the Cache Size</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,703 @@
<?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>Database Usage Example</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DBEntry.html" title="Chapter 8. Database Records" />
<link rel="previous" href="bindAPI.html" title="Using the BIND APIs" />
<link rel="next" href="Cursors.html" title="Chapter 9. Using Cursors" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Database Usage Example</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="bindAPI.html">Prev</a> </td>
<th width="60%" align="center">Chapter 8. Database Records</th>
<td width="20%" align="right"> <a accesskey="n" href="Cursors.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="dbtJavaUsage"></a>Database Usage Example</h2>
</div>
</div>
<div></div>
</div>
<p>
In <a href="CoreJavaUsage.html#MyDb">MyDbs Class</a> we created
a class that opens and closes databases for us.
We now make use of that class to load inventory data into
two databases that we will use for our inventory system.
</p>
<p>
Again, remember that you can find the complete implementation for these functions
in:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
<p>Note that in this example, we are going to save two types of
information. First there are a series of inventory records that identify
information about some food items (fruits, vegetables, and desserts).
These records identify particulars about each item such as the vendor that
the item can be obtained from, how much the vendor has in stock, the price
per unit, and so forth.</p>
<p>
We also want to manage vendor contact information, such as the
vendor's address and phone number, the sales representative's name
and his phone number, and so forth.
</p>
<div class="example">
<a id="inventoryjava"></a>
<p class="title">
<b>Example 8.1 Inventory.java</b>
</p>
<p>
All Inventory data is encapsulated in an instance of the following
class. Note that because this class is not serializable, we need a
custom tuple binding in order to place it on a <tt class="classname">DatabaseEntry</tt>
object. Because the <tt class="classname">TupleInput</tt> and
<tt class="classname">TupleOutput</tt> classes used by custom tuple bindings
support Java numerical types and not Java numerical classes, we use
<tt class="literal">int</tt> and <tt class="literal">float</tt> here instead of the
corresponding <tt class="classname">Integer</tt> and <tt class="classname">Float</tt>
classes.
</p>
<a id="java_dbt16"></a>
<pre class="programlisting">// File Inventory.java
package db.GettingStarted;
public class Inventory {
private String sku;
private String itemName;
private String category;
private String vendor;
private int vendorInventory;
private float vendorPrice;
public void setSku(String data) {
sku = data;
}
public void setItemName(String data) {
itemName = data;
}
public void setCategory(String data) {
category = data;
}
public void setVendorInventory(int data) {
vendorInventory = data;
}
public void setVendor(String data) {
vendor = data;
}
public void setVendorPrice(float data) {
vendorPrice = data;
}
public String getSku() { return sku; }
public String getItemName() { return itemName; }
public String getCategory() { return category; }
public int getVendorInventory() { return vendorInventory; }
public String getVendor() { return vendor; }
public float getVendorPrice() { return vendorPrice; }
} </pre>
</div>
<div class="example">
<a id="vendorjava"></a>
<p class="title">
<b>Example 8.2 Vendor.java</b>
</p>
<p>
The data for vendor records are stored in instances of the following
class. Notice that we are using serialization with this class for no
other reason than to demonstrate serializing a class instance.
</p>
<a id="java_dbt17"></a>
<pre class="programlisting">// File Vendor.java
package db.GettingStarted;
import java.io.Serializable;
public class Vendor implements Serializable {
private String repName;
private String address;
private String city;
private String state;
private String zipcode;
private String bizPhoneNumber;
private String repPhoneNumber;
private String vendor;
public void setRepName(String data) {
repName = data;
}
public void setAddress(String data) {
address = data;
}
public void setCity(String data) {
city = data;
}
public void setState(String data) {
state = data;
}
public void setZipcode(String data) {
zipcode = data;
}
public void setBusinessPhoneNumber(String data) {
bizPhoneNumber = data;
}
public void setRepPhoneNumber(String data) {
repPhoneNumber = data;
}
public void setVendorName(String data) {
vendor = data;
}
...
// Corresponding getter methods omitted for brevity.
// See examples/je/gettingStarted/Vendor.java
// for a complete implementation of this class.
} </pre>
</div>
<p>
Because we will not be using serialization to convert our
<tt class="classname">Inventory</tt> objects to a <tt class="classname">DatabaseEntry</tt>
object, we need a custom tuple binding:
</p>
<div class="example">
<a id="InventoryJavaBinding"></a>
<p class="title">
<b>Example 8.3 InventoryBinding.java</b>
</p>
<a id="java_dbt18"></a>
<pre class="programlisting">// File InventoryBinding.java
package db.GettingStarted;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
public class InventoryBinding extends TupleBinding {
// Implement this abstract method. Used to convert
// a DatabaseEntry to an Inventory object.
public Object entryToObject(TupleInput ti) {
String sku = ti.readString();
String itemName = ti.readString();
String category = ti.readString();
String vendor = ti.readString();
int vendorInventory = ti.readInt();
float vendorPrice = ti.readFloat();
Inventory inventory = new Inventory();
inventory.setSku(sku);
inventory.setItemName(itemName);
inventory.setCategory(category);
inventory.setVendor(vendor);
inventory.setVendorInventory(vendorInventory);
inventory.setVendorPrice(vendorPrice);
return inventory;
}
// Implement this abstract method. Used to convert a
// Inventory object to a DatabaseEntry object.
public void objectToEntry(Object object, TupleOutput to) {
Inventory inventory = (Inventory)object;
to.writeString(inventory.getSku());
to.writeString(inventory.getItemName());
to.writeString(inventory.getCategory());
to.writeString(inventory.getVendor());
to.writeInt(inventory.getVendorInventory());
to.writeFloat(inventory.getVendorPrice());
}
} </pre>
</div>
<p>
In order to store the data identified above, we write the
<tt class="classname">ExampleDatabaseLoad</tt> application. This application
loads the inventory and vendor databases for you.
</p>
<p>
Inventory information is stored in a <tt class="classname">Database</tt>
dedicated for that purpose. The key for each such record is a product
SKU. The inventory data stored in this database are objects of the
<tt class="classname">Inventory</tt> class (see <a href="dbtJavaUsage.html#inventoryjava">Inventory.java</a> for more information).
<tt class="classname">ExampleDatabaseLoad</tt> loads the inventory database
as follows:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Reads the inventory data from a flat text file prepared in
advance for this purpose.
</p>
</li>
<li>
<p>
Uses <tt class="classname">java.lang.String</tt> to create a key based
on the item's SKU.
</p>
</li>
<li>
<p>Uses an <tt class="classname">Inventory</tt> class instance for the
record data. This object is stored on a <tt class="classname">DatabaseEntry</tt>
object using <tt class="classname">InventoryBinding</tt>, a custom tuple
binding that we implemented above.</p>
</li>
<li>
<p>Saves each record to the inventory database.</p>
</li>
</ol>
</div>
<p>Vendor information is also stored in a <tt class="classname">Database</tt>
dedicated for that purpose. The vendor data stored in this database are objects of the
<tt class="classname">Vendor</tt> class (see <a href="dbtJavaUsage.html#vendorjava">Vendor.java</a> for more information). To load this
<tt class="classname">Database</tt>, <tt class="classname">ExampleDatabaseLoad</tt>
does the following:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Reads the vendor data from a flat text file prepared in advance
for this purpose.</p>
</li>
<li>
<p>Uses the vendor's name as the record's key.</p>
</li>
<li>
<p>Uses a <tt class="classname">Vendor</tt> class instance for the
record data. This object is stored on a <tt class="classname">DatabaseEntry</tt>
object using <tt class="classname">com.sleepycat.bind.serial.SerialBinding</tt>.</p>
</li>
</ol>
</div>
<div class="example">
<a id="dbsStoredClass"></a>
<p class="title">
<b>Example 8.4 Stored Class Catalog Management with MyDbs</b>
</p>
<p>
Before we can write <tt class="classname">ExampleDatabaseLoad</tt>, we need to update
<tt class="filename">MyDbs.java</tt> to support the class catalogs that we need for this application.
</p>
<p>
To do this, we start by importing an additional class to support stored class catalogs:
</p>
<a id="java_dbt19"></a>
<pre class="programlisting">// File: MyDbs.java
package db.GettingStarted;
<b class="userinput"><tt>import com.sleepycat.bind.serial.StoredClassCatalog;</tt></b>
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
import java.io.FileNotFoundException; </pre>
<p>
We also need to add two additional private data members to this class. One
supports the database used for the class catalog, and the other is used as a
handle for the class catalog itself.
</p>
<a id="java_dbt20"></a>
<pre class="programlisting">public class MyDbs {
// The databases that our application uses
private Database vendorDb = null;
private Database inventoryDb = null;
<b class="userinput"><tt>private Database classCatalogDb = null;
// Needed for object serialization
private StoredClassCatalog classCatalog;</tt></b>
private String vendordb = "VendorDB.db";
private String inventorydb = "InventoryDB.db";
<b class="userinput"><tt>private String classcatalogdb = "ClassCatalogDB.db";</tt></b>
// Our constructor does nothing
public MyDbs() {} </pre>
<p>
Next we need to update the <tt class="methodname">MyDbs.setup()</tt> method
to open the class catalog database and create the class catalog.
</p>
<a id="java_dbt21"></a>
<pre class="programlisting"> // The setup() method opens all our databases
// for us.
public void setup(String databasesHome)
throws DatabaseException {
DatabaseConfig myDbConfig = new DatabaseConfig();
...
// Database configuration omitted for brevity
...
// Now open, or create and open, our databases
// Open the vendors and inventory databases
try {
vendordb = databasesHome + "/" + vendordb;
vendorDb = new Database(vendordb,
null,
myDbConfig);
inventorydb = databasesHome + "/" + inventorydb;
inventoryDb = new Database(inventorydb,
null,
myDbConfig);
<b class="userinput"><tt>// Open the class catalog db. This is used to
// optimize class serialization.
classcatalogdb = databasesHome + "/" + classcatalogdb;
classCatalogDb = new Database(classcatalogdb,
null,
myDbConfig); </tt></b>
} catch(FileNotFoundException fnfe) {
System.err.println("MyDbs: " + fnfe.toString());
System.exit(-1);
}
} </pre>
<p>
Finally we need a getter method to return the class catalog. Note that we do not provide a getter for
the catalog database itself our application has no need for that.
</p>
<p>
We also update our <tt class="methodname">close()</tt> to close our class catalog.
</p>
<a id="java_dbt22"></a>
<pre class="programlisting"> // getter methods
public Database getVendorDB() {
return vendorDb;
}
public Database getInventoryDB() {
return inventoryDb;
}
<b class="userinput"><tt>public StoredClassCatalog getClassCatalog() {
return classCatalog;
}</tt></b>
</pre>
<p>
Finally, we need our <tt class="methodname">close()</tt> method:
</p>
<a id="java_dbt23"></a>
<pre class="programlisting">
// Close the databases
public void close() {
try {
if (vendorDb != null) {
vendorDb.close();
}
if (inventoryDb != null) {
inventoryDb.close();
}
<b class="userinput"><tt>if (classCatalogDb != null) {
classCatalogDb.close();
}</tt></b>
} catch(DatabaseException dbe) {
System.err.println("Error closing MyDbs: " +
dbe.toString());
System.exit(-1);
}
}
} </pre>
</div>
<p>
So far we have identified the data that we want to store in our
databases and how we will convert that data in and out of
<tt class="classname">DatabaseEntry</tt> objects for database storage. We
have also updated <tt class="classname">MyDbs</tt> to manage our databases
for us. Now we write <tt class="classname">ExampleDatabaseLoad</tt> to
actually put the inventory and vendor data into their respective
databases. Because of the work that we have done so far, this
application is actually fairly simple to write.
</p>
<div class="example">
<a id="EDL"></a>
<p class="title">
<b>Example 8.5 ExampleDatabaseLoad.java</b>
</p>
<p>First we need the usual series of import statements:</p>
<a id="java_dbt24"></a>
<pre class="programlisting">// File: ExampleDatabaseLoad.java
package db.GettingStarted;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException; </pre>
<p>Next comes the class declaration and the private data members that
we need for this class. Most of these are setting up default values for
the program.</p>
<p>Note that two <tt class="classname">DatabaseEntry</tt> objects are
instantiated here. We will reuse these for every database operation that
this program performs. Also a <tt class="classname">MyDbEnv</tt> object is
instantiated here. We can do this because its constructor never throws
an exception. See <a href="dbtJavaUsage.html#dbsStoredClass">Stored Class Catalog Management with MyDbs</a> for
its implementation details.</p>
<p>Finally, the <tt class="filename">inventory.txt</tt> and
<tt class="filename">vendors.txt</tt> file can be found in the GettingStarted
examples directory along with the classes described in this extended
example.</p>
<a id="java_dbt25"></a>
<pre class="programlisting">public class ExampleDatabaseLoad {
private static String myDbsPath = "./";
private static File inventoryFile = new File("./inventory.txt");
private static File vendorsFile = new File("./vendors.txt");
// DatabaseEntries used for loading records
private static DatabaseEntry theKey = new DatabaseEntry();
private static DatabaseEntry theData = new DatabaseEntry();
// Encapsulates the databases.
private static MyDbs myDbs = new MyDbs(); </pre>
<p>
Next comes the <tt class="methodname">usage()</tt> and
<tt class="methodname">main()</tt> methods. Notice the exception handling
in the <tt class="methodname">main()</tt> method. This is the only place in the application where we
catch exceptions. For this reason, we must catch
<tt class="classname">DatabaseException</tt> which is thrown by the
<tt class="literal">com.sleepycat.db.*</tt> classes.
</p>
<p>Also notice the call to <tt class="methodname">MyDbs.close()</tt>
in the <tt class="literal">finally</tt> block. This is the only place in the
application where <tt class="methodname">MyDbs.close()</tt> is called.
<tt class="methodname">MyDbs.close()</tt> is responsible for closing
all open <tt class="classname">Database</tt>
handles for you.</p>
<a id="java_dbt26"></a>
<pre class="programlisting"> private static void usage() {
System.out.println("ExampleDatabaseLoad [-h &lt;database home&gt;]");
System.out.println(" [-s &lt;selections file&gt;] [-v &lt;vendors file&gt;]");
System.exit(-1);
}
public static void main(String args[]) {
ExampleDatabaseLoad edl = new ExampleDatabaseLoad();
try {
edl.run(args);
} catch (DatabaseException dbe) {
System.err.println("ExampleDatabaseLoad: " + dbe.toString());
dbe.printStackTrace();
} catch (Exception e) {
System.out.println("Exception: " + e.toString());
e.printStackTrace();
} finally {
myDbs.close();
}
System.out.println("All done.");
} </pre>
<p>Next we write the <tt class="methodname">ExampleDatabaseLoad.run()</tt>
method. This method is responsible for initializing all objects.
Because our environment and databases are all opened using the
<tt class="methodname">MyDbs.setup()</tt> method, <tt class="methodname">ExampleDatabaseLoad.run()</tt>
method is only responsible for calling <tt class="methodname">MyDbs.setup()</tt> and then calling
the <tt class="classname">ExampleDatabaseLoad</tt> methods that actually load the databases.
</p>
<a id="java_dbt27"></a>
<pre class="programlisting"> private void run(String args[]) throws DatabaseException {
// Parse the arguments list
parseArgs(args);
myDbs.setup(myDbsPath); // path to the environment home
System.out.println("loading vendors db.");
loadVendorsDb();
System.out.println("loading inventory db.");
loadInventoryDb();
} </pre>
<p>This next method loads the vendor database. This method
uses serialization to convert the <tt class="classname">Vendor</tt> object
to a <tt class="classname">DatabaseEntry</tt> object.</p>
<a id="java_dbt28"></a>
<pre class="programlisting"> private void loadVendorsDb()
throws DatabaseException {
// loadFile opens a flat-text file that contains our data
// and loads it into a list for us to work with. The integer
// parameter represents the number of fields expected in the
// file.
List vendors = loadFile(vendorsFile, 8);
// Now load the data into the database. The vendor's name is the
// key, and the data is a Vendor class object.
// Need a serial binding for the data
EntryBinding dataBinding =
new SerialBinding(myDbs.getClassCatalog(), Vendor.class);
for (int i = 0; i &lt; vendors.size(); i++) {
String[] sArray = (String[])vendors.get(i);
Vendor theVendor = new Vendor();
theVendor.setVendorName(sArray[0]);
theVendor.setAddress(sArray[1]);
theVendor.setCity(sArray[2]);
theVendor.setState(sArray[3]);
theVendor.setZipcode(sArray[4]);
theVendor.setBusinessPhoneNumber(sArray[5]);
theVendor.setRepName(sArray[6]);
theVendor.setRepPhoneNumber(sArray[7]);
// The key is the vendor's name.
// ASSUMES THE VENDOR'S NAME IS UNIQUE!
String vendorName = theVendor.getVendorName();
try {
theKey = new DatabaseEntry(vendorName.getBytes("UTF-8"));
} catch (IOException willNeverOccur) {}
// Convert the Vendor object to a DatabaseEntry object
// using our SerialBinding
dataBinding.objectToEntry(theVendor, theData);
// Put it in the database.
myDbs.getVendorDB().put(null, theKey, theData);
}
} </pre>
<p>Now load the inventory database. This method uses our
custom tuple binding (see <a href="dbtJavaUsage.html#InventoryJavaBinding">InventoryBinding.java</a>) to convert the <tt class="classname">Inventory</tt>
object to a <tt class="classname">DatabaseEntry</tt> object.</p>
<a id="java_dbt29"></a>
<pre class="programlisting"> private void loadInventoryDb()
throws DatabaseException {
// loadFile opens a flat-text file that contains our data
// and loads it into a list for us to work with. The integer
// parameter represents the number of fields expected in the
// file.
List inventoryArray = loadFile(inventoryFile, 6);
// Now load the data into the database. The item's sku is the
// key, and the data is an Inventory class object.
// Need a tuple binding for the Inventory class.
TupleBinding inventoryBinding = new InventoryBinding();
for (int i = 0; i &lt; inventoryArray.size(); i++) {
String[] sArray = (String[])inventoryArray.get(i);
String sku = sArray[1];
try {
theKey = new DatabaseEntry(sku.getBytes("UTF-8"));
} catch (IOException willNeverOccur) {}
Inventory theInventory = new Inventory();
theInventory.setItemName(sArray[0]);
theInventory.setSku(sArray[1]);
Float price = new Float(sArray[2]);
theInventory.setVendorPrice(price.floatValue());
Integer vInventory = new Integer(sArray[3]);
theInventory.setVendorInventory(vInventory.intValue());
theInventory.setCategory(sArray[4]);
theInventory.setVendor(sArray[5]);
// Place the Vendor object on the DatabaseEntry object using
// our the tuple binding we implemented in
// InventoryBinding.java
inventoryBinding.objectToEntry(theInventory, theData);
// Put it in the database. Note that this causes our
// secondary database to be automatically updated for us.
myDbs.getInventoryDB().put(null, theKey, theData);
}
}</pre>
<p>
The remainder of this application provides utility methods to
read a flat text file into an array of strings and parse the
command line options:
</p>
<a id="java_dbt30"></a>
<pre class="programlisting"> private static void parseArgs(String args[]) {
// Implementation omitted for brevity.
}
private List loadFile(File theFile, int numFields) {
List records = new ArrayList();
// Implementation omitted for brevity.
return records;
}
protected ExampleDatabaseLoad() {}
} </pre>
<p>
From the perspective of this document, these
things are relatively uninteresting. You can see how they are
implemented by looking at <tt class="filename">ExampleDatabaseLoad.java</tt>
in:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="bindAPI.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DBEntry.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="Cursors.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Using the BIND APIs </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 9. Using Cursors</td>
</tr>
</table>
</div>
</body>
</html>

283
docs/gsg/JAVA/dpl.html Normal file
View File

@@ -0,0 +1,283 @@
<?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>Part I. Programming with the Direct Persistence Layer</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="previous" href="EnvProps.html" title="Environment Properties" />
<link rel="next" href="persist_first.html" title="Chapter 3. Direct Persistence Layer First Steps" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Part I. Programming with the Direct Persistence Layer</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="EnvProps.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="persist_first.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="part" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a id="dpl"></a>Programming with the Direct Persistence Layer</h1>
</div>
</div>
<div></div>
</div>
<div class="partintro" lang="en" xml:lang="en">
<div>
<div></div>
<div></div>
</div>
<p>
This section discusses how to build an
application using the DPL. The DPL is ideally
suited for those applications that want a
mechanism for storing and managing Java class
objects in a DB database. Note that the DPL
is best suited for applications that work with
classes with a relatively static schema.
</p>
<p>
Also, the DPL requires Java 1.5.
</p>
<p>
If you want to use Java 1.4 for your DB
application, or if you are porting an application
from the Berkeley DB API, then you probably want
to use the base API instead of the DPL. For
information on using the base API, see
<a href="baseapi.html">Programming with the Base API</a>.
</p>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="chapter">
<a href="persist_first.html">3. Direct Persistence Layer First Steps</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="persist_first.html#entitystore">Entity Stores</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="persist_first.html#persist-open">Opening and Closing Environments and Stores</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="persistobject.html">Persistent Objects</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="saveret.html">Saving a Retrieving Data</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="persist_index.html">4. Working with Indices</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="persist_index.html#dplindexaccess">Accessing Indexes</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="persist_index.html#primaryindexaccess">Accessing Primary Indices</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="persist_index.html#secondaryindexaccess">Accessing Secondary Indices</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dplindexcreate.html">Creating Indexes</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#dplprimaryidxdecl">Declaring a Primary Indexes</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#dplsecondaryidxdecl">Declaring Secondary Indexes</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#foreignkey">Foreign Key Constraints</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="persist_access.html">5. Saving and Retrieving Objects</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="persist_access.html#simpleentity">A Simple Entity Class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleda.html">SimpleDA.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleput.html">Placing Objects in an Entity Store</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleget.html">Retrieving Objects from an Entity Store</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="getmultiple.html">Retrieving Multiple Objects</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_cursor_initialize">Cursor Initialization</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_dups">Working with Duplicate Keys</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_cursor_range">Key Ranges</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dpl_entityjoin.html">Join Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_delete.html">Deleting Entity Objects</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_replace.html">Replacing Entity Objects</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="dpl_example.html">6. A DPL Example</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="dpl_example.html#vendorclass">Vendor.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="inventoryclass.html">Inventory.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="mydbenv-persist.html">MyDbEnv</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dataaccessorclass.html">DataAccessor.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_exampledatabaseput.html">ExampleDatabasePut.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_exampleinventoryread.html">ExampleInventoryRead.class</a>
</span>
</dt>
</dl>
</dd>
</dl>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="EnvProps.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="index.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="persist_first.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Environment Properties </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 3. Direct Persistence Layer First Steps</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,87 @@
<?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>Deleting Entity Objects</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="dpl_entityjoin.html" title="Join Cursors" />
<link rel="next" href="dpl_replace.html" title="Replacing Entity Objects" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Deleting Entity Objects</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl_entityjoin.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl_replace.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="dpl_delete"></a>Deleting Entity Objects</h2>
</div>
</div>
<div></div>
</div>
<p>
The simplest way to remove an object from your entity store
is to delete it by its primary index. For example,
using the <tt class="classname">SimpleDA</tt> class that we
created earlier in this document
(see <a href="simpleda.html">SimpleDA.class</a>),
you can delete the <tt class="classname">SimpleEntityClass</tt>
object with a primary key of <tt class="literal">keyone</tt> as
follows:
</p>
<pre class="programlisting">sda.pIdx.delete("keyone");</pre>
<p>
You can also delete objects by their secondary keys. When
you do this, all objects related to the secondary key are
deleted, unless the key is a foreign object.
</p>
<p>
For example, the following deletes all
<tt class="classname">SimpleEntityClass</tt> with a secondary
key of <tt class="literal">skeyone</tt>:
</p>
<pre class="programlisting">sda.sIdx.delete("skeyone");</pre>
<p>
Finally, if you are indexing by foreign key, then the
results of deleting the key is determined by the foreign
key constraint that you have set for the index. See
<a href="dplindexcreate.html#foreignkey">Foreign Key Constraints</a>
for more information.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl_entityjoin.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl_replace.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Join Cursors </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Replacing Entity Objects</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,191 @@
<?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>Join Cursors</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="getmultiple.html" title="Retrieving Multiple Objects" />
<link rel="next" href="dpl_delete.html" title="Deleting Entity Objects" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Join Cursors</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="getmultiple.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl_delete.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="dpl_entityjoin"></a>Join Cursors</h2>
</div>
</div>
<div></div>
</div>
<p>
If you have two or more secondary indexes set for
an entity object, then you can retrieve sets of
objects based on the intersection of multiple
secondary index values. You do this using an
<tt class="classname">EntityJoin</tt>
class.
</p>
<p>
For example, suppose you had an entity class that
represented automobiles. In that case, you might
be storing information about automobiles such as
color, number of doors, fuel mileage,
automobile type, number of passengers, make, model, and year,
to name just a few.
</p>
<p>
If you created a secondary index based this
information, then you could use an
<tt class="classname">EntityJoin</tt> to return
all those objects representing cars with, say, two
doors, that were built in 2002, and which are green
in color.
</p>
<p>
To create a join cursor, you:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Open the primary index for the
entity class on which you want to
perform the join.
</p>
</li>
<li>
<p>
Open the secondary indexes that you
want to use for the join.
</p>
</li>
<li>
<p>
Instantiate an
<tt class="classname">EntityJoin</tt>
object (you use the primary index
to do this).
</p>
</li>
<li>
<p>
Use two or more calls to
<tt class="methodname">EntityJoin.addCondition()</tt>
to identify the secondary indexes
and their values that you want to use
for the equality match.
</p>
</li>
<li>
<p>
Call
<tt class="methodname">EntityJoin.entities()</tt>
to obtain a cursor that you can use
to iterate over the join results.
</p>
</li>
</ol>
</div>
<p>
For example, suppose we had an entity class
that included the following features:
</p>
<pre class="programlisting">package persist.gettingStarted;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.PrimaryKey;
import static com.sleepycat.persist.model.Relationship.*;
import com.sleepycat.persist.model.SecondaryKey;
@Entity
public class Automobiles {
// Primary key is the vehicle identification number
@PrimaryKey
private String vin;
// Secondary key is the vehicle's make
@SecondaryKey(relate=MANY_TO_ONE)
private String make;
// Secondary key is the vehicle's color
@SecondaryKey(relate=MANY_TO_ONE)
private String color;
...
public String getVIN() {
return vin;
}
public String getMake() {
return make;
}
public String getColor() {
return color;
}
... </pre>
<p>
Then we could perform an entity join that searches for all the
red automobiles made by Toyota as follows:
</p>
<pre class="programlisting">
PrimaryIndex&lt;String,Automobiles&gt; vin_pidx;
SecondaryIndex&lt;String,String,Automobiles&gt; make_sidx;
SecondaryIndex&lt;String,String,Automobiles&gt; color_sidx;
EntityJoin&lt;String,Automobiles&gt; join = new EntityJoin(vin_pidx);
join.addCondition(make_sidx,"Toyota");
join.addCondition(color_sidx,"Red");
// Now iterate over the results of the join operation
EntityCursor&lt;Automobiles&gt; join_cursor = join.entities();
try {
for (Automobiles autoi : join_cursor) {
// do something with each object "autoi"
}
// Always make sure the cursor is closed when we are done with it.
} finally {
join_cursor.close();
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="getmultiple.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl_delete.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Retrieving Multiple Objects </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Deleting Entity Objects</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,263 @@
<?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>Chapter 6. A DPL Example</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl.html" title="Part I. Programming with the Direct Persistence Layer" />
<link rel="previous" href="dpl_replace.html" title="Replacing Entity Objects" />
<link rel="next" href="inventoryclass.html" title="Inventory.class" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 6. A DPL Example</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl_replace.html">Prev</a> </td>
<th width="60%" align="center">Part I. Programming with the Direct Persistence Layer</th>
<td width="20%" align="right"> <a accesskey="n" href="inventoryclass.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="dpl_example"></a>Chapter 6. A DPL Example</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="dpl_example.html#vendorclass">Vendor.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="inventoryclass.html">Inventory.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="mydbenv-persist.html">MyDbEnv</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dataaccessorclass.html">DataAccessor.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_exampledatabaseput.html">ExampleDatabasePut.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_exampleinventoryread.html">ExampleInventoryRead.class</a>
</span>
</dt>
</dl>
</div>
<p>
In order to illustrate DPL usage, we provide a
complete working example in this chapter. This example
reads and writes inventory and vendor information for a
mythical business. The application consists of the
following classes:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Several classes used to encapsulate our
application's data. See
<a href="dpl_example.html#vendorclass">Vendor.class</a>
and
<a href="inventoryclass.html">Inventory.class</a>.
</p>
</li>
<li>
<p>
A convenience class used to open and close
our environment and entity store. See
<a href="mydbenv-persist.html">MyDbEnv</a>.
</p>
</li>
<li>
<p>
A class that loads data into the store. See
<a href="dpl_exampledatabaseput.html">ExampleDatabasePut.class</a>.
</p>
</li>
<li>
<p>
Finally, a class that reads data from the
store. See
<a href="dpl_exampleinventoryread.html">ExampleInventoryRead.class</a>.
</p>
</li>
</ul>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="vendorclass"></a>Vendor.class</h2>
</div>
</div>
<div></div>
</div>
<p>
The simplest class that our example wants to store contains
vendor contact information. This class contains no
secondary indices so all we have to do is identify it
as an entity class and identify the field in the
class used for the primary key.
</p>
<p>
In the following example, we identify the
<tt class="literal">vendor</tt> data member as containing the
primary key. This data member is meant to contain a
vendor's name. Because of the way we will use our
<tt class="classname">EntityStore</tt>, the value
provided for this data member must be unique within
the store or runtime errors will result.
</p>
<p>
When used with the DPL, our
<tt class="classname">Vendor</tt> class appears as
follows. Notice that the <tt class="literal">@Entity</tt>
annotation appears immediately before the class
declaration, and the <tt class="literal">@PrimaryKey</tt>
annotation appears immediately before the
<tt class="literal">vendor</tt> data member declaration.
</p>
<pre class="programlisting">package persist.gettingStarted;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.PrimaryKey;
@Entity
public class Vendor {
private String address;
private String bizPhoneNumber;
private String city;
private String repName;
private String repPhoneNumber;
private String state;
// Primary key is the vendor's name
// This assumes that the vendor's name is
// unique in the database.
@PrimaryKey
private String vendor;
private String zipcode;
public void setRepName(String data) {
repName = data;
}
public void setAddress(String data) {
address = data;
}
public void setCity(String data) {
city = data;
}
public void setState(String data) {
state = data;
}
public void setZipcode(String data) {
zipcode = data;
}
public void setBusinessPhoneNumber(String data) {
bizPhoneNumber = data;
}
public void setRepPhoneNumber(String data) {
repPhoneNumber = data;
}
public void setVendorName(String data) {
vendor = data;
}
public String getRepName() {
return repName;
}
public String getAddress() {
return address;
}
public String getCity() {
return city;
}
public String getState() {
return state;
}
public String getZipcode() {
return zipcode;
}
public String getBusinessPhoneNumber() {
return bizPhoneNumber;
}
public String getRepPhoneNumber() {
return repPhoneNumber;
}
} </pre>
<p>
For this class, the <tt class="literal">vendor</tt> value is set for an individual
<tt class="classname">Vendor</tt> class object by
the <tt class="methodname">setVendorName()</tt>
method. If our example code fails to set this
value before storing the object, the data
member used to store the primary key is set to a
null value. This would result in a runtime
error.
</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl_replace.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="inventoryclass.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Replacing Entity Objects </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Inventory.class</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,334 @@
<?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>ExampleDatabasePut.class</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl_example.html" title="Chapter 6. A DPL Example" />
<link rel="previous" href="dataaccessorclass.html" title="DataAccessor.class" />
<link rel="next" href="dpl_exampleinventoryread.html" title="ExampleInventoryRead.class" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">ExampleDatabasePut.class</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dataaccessorclass.html">Prev</a> </td>
<th width="60%" align="center">Chapter 6. A DPL Example</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl_exampleinventoryread.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="dpl_exampledatabaseput"></a>ExampleDatabasePut.class</h2>
</div>
</div>
<div></div>
</div>
<p>
Our example reads inventory and vendor information from
flat text files, encapsulates this data in objects of
the appropriate type, and then writes each object to an
<tt class="classname">EntityStore</tt>.
</p>
<p>
To begin, we import the Java classes that our example
needs. Most of the imports are related to reading the raw
data from flat text files and breaking them apart for usage
with our data classes. We also import classes from the
DB package, but we do not actually import any classes
from the DPL. The reason why is because we have
placed almost all of our DPL work off into
other classes, so there is no need for direct usage of
those APIs here.
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import com.sleepycat.db.DatabaseException; </pre>
<p>
Now we can begin the class itself. Here we set default paths
for the on-disk resources that we require (the environment
home, and the location of the text files containing our sample
data). We also declare <tt class="classname">DataAccessor</tt>
and <tt class="classname">MyDbEnv</tt> members. We describe these
classes and show their implementation in
<a href="dataaccessorclass.html">DataAccessor.class</a>
and
<a href="mydbenv-persist.html">MyDbEnv</a>.
</p>
<pre class="programlisting">public class ExampleDatabasePut {
private static File myDbEnvPath = new File("/tmp/JEDB");
private static File inventoryFile = new File("./inventory.txt");
private static File vendorsFile = new File("./vendors.txt");
private DataAccessor da;
// Encapsulates the environment and data store.
private static MyDbEnv myDbEnv = new MyDbEnv();</pre>
<p>
Next, we provide our <tt class="methodname">usage()</tt>
method. The command line options provided there are necessary
only if the default values to the on-disk resources are not
sufficient.
</p>
<pre class="programlisting"> private static void usage() {
System.out.println("ExampleDatabasePut [-h &lt;env directory&gt;]");
System.out.println(" [-i &lt;inventory file&gt;] [-v &lt;vendors file&gt;]");
System.exit(-1);
} </pre>
<p>
Our <tt class="methodname">main()</tt> method is also reasonably
self-explanatory. We simply instantiate an
<tt class="classname">ExampleDatabasePut</tt> object there and then
call its <tt class="methodname">run()</tt> method. We also provide a
top-level <tt class="literal">try</tt> block there for any exceptions that might be thrown
during runtime.
</p>
<p>
Notice that the <tt class="literal">finally</tt> statement in the
top-level <tt class="literal">try</tt> block calls
<tt class="methodname">MyDbEnv.close()</tt>. This method closes our
<tt class="classname">EntityStore</tt> and <tt class="classname">Environment</tt>
objects. By placing it here in the <tt class="literal">finally</tt>
statement, we can make sure that our store and environment are
always cleanly closed.
</p>
<pre class="programlisting"> public static void main(String args[]) {
ExampleDatabasePut edp = new ExampleDatabasePut();
try {
edp.run(args);
} catch (DatabaseException dbe) {
System.err.println("ExampleDatabasePut: " + dbe.toString());
dbe.printStackTrace();
} catch (Exception e) {
System.out.println("Exception: " + e.toString());
e.printStackTrace();
} finally {
myDbEnv.close();
}
System.out.println("All done.");
} </pre>
<p>
Our <tt class="methodname">run()</tt> method does four
things. It calls <tt class="methodname">MyDbEnv.setup()</tt>,
which opens our <tt class="classname">Environment</tt> and
<tt class="classname">EntityStore</tt>. It then instantiates a
<tt class="classname">DataAccessor</tt> object, which we will use
to write data to the store. It calls
<tt class="methodname">loadVendorsDb()</tt> which loads all of the
vendor information. And then it calls
<tt class="methodname">loadInventoryDb()</tt> which loads all of
the inventory information.
</p>
<p>
Notice that the <tt class="classname">MyDbEnv</tt>
object is being setup as read-write. This results in the
<tt class="classname">EntityStore</tt> being opened for
transactional support.
(See <a href="mydbenv-persist.html">MyDbEnv</a>
for implementation details.)
</p>
<pre class="programlisting"> private void run(String args[])
throws DatabaseException {
// Parse the arguments list
parseArgs(args);
myDbEnv.setup(myDbEnvPath, // Path to the environment home
false); // Environment read-only?
// Open the data accessor. This is used to store
// persistent objects.
da = new DataAccessor(myDbEnv.getEntityStore());
System.out.println("loading vendors db....");
loadVendorsDb();
System.out.println("loading inventory db....");
loadInventoryDb();
} </pre>
<p>
We can now implement the <tt class="methodname">loadVendorsDb()</tt>
method. This method is responsible for reading the vendor
contact information from the appropriate flat-text file,
populating <tt class="classname">Vendor</tt> class objects with the
data and then writing it to the <tt class="classname">EntityStore</tt>.
As explained above, each individual object is written with
transactional support. However, because a transaction handle is
not explicitly used, the write is performed using auto-commit.
This happens because the <tt class="classname">EntityStore</tt>
was opened to support transactions.
</p>
<p>
To actually write each class to the
<tt class="classname">EntityStore</tt>, we simply call the
<tt class="methodname">PrimaryIndex.put()</tt> method for the
<tt class="classname">Vendor</tt> entity instance. We obtain this
method from our <tt class="classname">DataAccessor</tt>
class.
</p>
<pre class="programlisting"> private void loadVendorsDb()
throws DatabaseException {
// loadFile opens a flat-text file that contains our data
// and loads it into a list for us to work with. The integer
// parameter represents the number of fields expected in the
// file.
List vendors = loadFile(vendorsFile, 8);
// Now load the data into the store.
for (int i = 0; i &lt; vendors.size(); i++) {
String[] sArray = (String[])vendors.get(i);
Vendor theVendor = new Vendor();
theVendor.setVendorName(sArray[0]);
theVendor.setAddress(sArray[1]);
theVendor.setCity(sArray[2]);
theVendor.setState(sArray[3]);
theVendor.setZipcode(sArray[4]);
theVendor.setBusinessPhoneNumber(sArray[5]);
theVendor.setRepName(sArray[6]);
theVendor.setRepPhoneNumber(sArray[7]);
// Put it in the store.
da.vendorByName.put(theVendor);
}
} </pre>
<p>
Now we can implement our <tt class="methodname">loadInventoryDb()</tt>
method. This does exactly the same thing as the
<tt class="methodname">loadVendorsDb()</tt>
method.
</p>
<pre class="programlisting"> private void loadInventoryDb()
throws DatabaseException {
// loadFile opens a flat-text file that contains our data
// and loads it into a list for us to work with. The integer
// parameter represents the number of fields expected in the
// file.
List inventoryArray = loadFile(inventoryFile, 6);
// Now load the data into the store. The item's sku is the
// key, and the data is an Inventory class object.
for (int i = 0; i &lt; inventoryArray.size(); i++) {
String[] sArray = (String[])inventoryArray.get(i);
String sku = sArray[1];
Inventory theInventory = new Inventory();
theInventory.setItemName(sArray[0]);
theInventory.setSku(sArray[1]);
theInventory.setVendorPrice(
(new Float(sArray[2])).floatValue());
theInventory.setVendorInventory(
(new Integer(sArray[3])).intValue());
theInventory.setCategory(sArray[4]);
theInventory.setVendor(sArray[5]);
// Put it in the store. Note that this causes our secondary key
// to be automatically updated for us.
da.inventoryBySku.put(theInventory);
}
} </pre>
<p>
The remainder of this example simple parses the command line
and loads data from a flat-text file. There is nothing here
that is of specific interest to the DPL, but we
show this part of the example anyway in the interest of
completeness.
</p>
<pre class="programlisting"> private static void parseArgs(String args[]) {
for(int i = 0; i &lt; args.length; ++i) {
if (args[i].startsWith("-")) {
switch(args[i].charAt(1)) {
case 'h':
myDbEnvPath = new File(args[++i]);
break;
case 'i':
inventoryFile = new File(args[++i]);
break;
case 'v':
vendorsFile = new File(args[++i]);
break;
default:
usage();
}
}
}
}
private List loadFile(File theFile, int numFields) {
List&lt;String[]&gt; records = new ArrayList&lt;String[]&gt;();
try {
String theLine = null;
FileInputStream fis = new FileInputStream(theFile);
BufferedReader br =
new BufferedReader(new InputStreamReader(fis));
while((theLine=br.readLine()) != null) {
String[] theLineArray = theLine.split("#");
if (theLineArray.length != numFields) {
System.out.println("Malformed line found in " +
theFile.getPath());
System.out.println("Line was: '" + theLine);
System.out.println("length found was: " +
theLineArray.length);
System.exit(-1);
}
records.add(theLineArray);
}
// Close the input stream handle
fis.close();
} catch (FileNotFoundException e) {
System.err.println(theFile.getPath() + " does not exist.");
e.printStackTrace();
usage();
} catch (IOException e) {
System.err.println("IO Exception: " + e.toString());
e.printStackTrace();
System.exit(-1);
}
return records;
}
protected ExampleDatabasePut() {}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dataaccessorclass.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl_example.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl_exampleinventoryread.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">DataAccessor.class </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> ExampleInventoryRead.class</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,269 @@
<?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>ExampleInventoryRead.class</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl_example.html" title="Chapter 6. A DPL Example" />
<link rel="previous" href="dpl_exampledatabaseput.html" title="ExampleDatabasePut.class" />
<link rel="next" href="baseapi.html" title="Part II. Programming with the Base API" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">ExampleInventoryRead.class</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl_exampledatabaseput.html">Prev</a> </td>
<th width="60%" align="center">Chapter 6. A DPL Example</th>
<td width="20%" align="right"> <a accesskey="n" href="baseapi.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="dpl_exampleinventoryread"></a>ExampleInventoryRead.class</h2>
</div>
</div>
<div></div>
</div>
<p>
<tt class="classname">ExampleInventoryRead</tt>
retrieves
inventory information from our entity store and
displays it. When it displays each inventory item, it
also displays the related vendor contact information.
</p>
<p>
<tt class="classname">ExampleInventoryRead</tt>
can do one of two things. If you provide no search
criteria, it displays all of the inventory items in the
store. If you provide an item name (using the
<tt class="literal">-s</tt> command line switch), then just
those inventory items using that name are displayed.
</p>
<p>
The beginning of our example is almost identical to our
<tt class="classname">ExampleDatabasePut</tt>
example program. We
repeat that example code here for the sake of
completeness. For a complete walk-through of it, see
the previous section (<a href="dpl_exampledatabaseput.html">ExampleDatabasePut.class</a>).
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import java.io.IOException;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.persist.EntityCursor;
public class ExampleInventoryRead {
private static File myDbEnvPath =
new File("/tmp/JEDB");
private DataAccessor da;
// Encapsulates the database environment.
private static MyDbEnv myDbEnv = new MyDbEnv();
// The item to locate if the -s switch is used
private static String locateItem;
private static void usage() {
System.out.println("ExampleInventoryRead [-h &lt;env directory&gt;]" +
"[-s &lt;item to locate&gt;]");
System.exit(-1);
}
public static void main(String args[]) {
ExampleInventoryRead eir = new ExampleInventoryRead();
try {
eir.run(args);
} catch (DatabaseException dbe) {
System.err.println("ExampleInventoryRead: " + dbe.toString());
dbe.printStackTrace();
} finally {
myDbEnv.close();
}
System.out.println("All done.");
}
private void run(String args[])
throws DatabaseException {
// Parse the arguments list
parseArgs(args);
myDbEnv.setup(myDbEnvPath, // path to the environment home
true); // is this environment read-only?
// Open the data accessor. This is used to retrieve
// persistent objects.
da = new DataAccessor(myDbEnv.getEntityStore());
// If a item to locate is provided on the command line,
// show just the inventory items using the provided name.
// Otherwise, show everything in the inventory.
if (locateItem != null) {
showItem();
} else {
showAllInventory();
}
} </pre>
<p>
The first method that we provide is used to show inventory
items related to a given inventory name. This method is called
only if an inventory name is passed to
<tt class="classname">ExampleInventoryRead</tt>
via the <tt class="literal">-s</tt> option. Given the sample data
that we provide with this example, each matching inventory name
will result in the display of three inventory objects.
</p>
<p>
To display these objects we use the
<tt class="classname">Inventory</tt> class'
<tt class="literal">inventoryByName</tt> secondary index to retrieve
an <tt class="classname">EntityCursor</tt>, and then we iterate
over the resulting objects using the cursor.
</p>
<p>
Notice that this method calls
<tt class="methodname">displayInventoryRecord()</tt>
to display each individual object. We show this
method a little later in the example.
</p>
<pre class="programlisting"> // Shows all the inventory items that exist for a given
// inventory name.
private void showItem() throws DatabaseException {
// Use the inventory name secondary key to retrieve
// these objects.
EntityCursor&lt;Inventory&gt; items =
da.inventoryByName.subIndex(locateItem).entities();
try {
for (Inventory item : items) {
displayInventoryRecord(item);
}
} finally {
items.close();
}
} </pre>
<p>
Next we implement <tt class="methodname">showAllInventory()</tt>,
which shows all of the <tt class="classname">Inventory</tt>
objects in the store. To do this, we
obtain an <tt class="classname">EntityCursor</tt>
from the <tt class="classname">Inventory</tt> class'
primary index and, again, we iterate using that cursor.
</p>
<pre class="programlisting"> // Displays all the inventory items in the store
private void showAllInventory()
throws DatabaseException {
// Get a cursor that will walk every
// inventory object in the store.
EntityCursor&lt;Inventory&gt; items =
da.inventoryBySku.entities();
try {
for (Inventory item : items) {
displayInventoryRecord(item);
}
} finally {
items.close();
}
} </pre>
<p>
Now we implement
<tt class="methodname">displayInventoryRecord()</tt>. This
uses the getter methods on the <tt class="classname">Inventory</tt>
class to obtain the information that we want to display.
The only thing interesting about this method is that we
obtain <tt class="classname">Vendor</tt> objects within.
The vendor objects are retrieved <tt class="classname">Vendor</tt>
objects using their primary index. We get the key
for the retrieval from the <tt class="classname">Inventory</tt>
object that we are displaying at the time.
</p>
<pre class="programlisting"> private void displayInventoryRecord(Inventory theInventory)
throws DatabaseException {
System.out.println(theInventory.getSku() + ":");
System.out.println("\t " + theInventory.getItemName());
System.out.println("\t " + theInventory.getCategory());
System.out.println("\t " + theInventory.getVendor());
System.out.println("\t\tNumber in stock: " +
theInventory.getVendorInventory());
System.out.println("\t\tPrice per unit: " +
theInventory.getVendorPrice());
System.out.println("\t\tContact: ");
Vendor theVendor =
da.vendorByName.get(theInventory.getVendor());
assert theVendor != null;
System.out.println("\t\t " + theVendor.getAddress());
System.out.println("\t\t " + theVendor.getCity() + ", " +
theVendor.getState() + " " + theVendor.getZipcode());
System.out.println("\t\t Business Phone: " +
theVendor.getBusinessPhoneNumber());
System.out.println("\t\t Sales Rep: " +
theVendor.getRepName());
System.out.println("\t\t " +
theVendor.getRepPhoneNumber());
} </pre>
<p>
The last remaining parts of the example are used to parse
the command line. This is not very
interesting for our purposes here, but we show it anyway
for the sake of completeness.
</p>
<pre class="programlisting"> protected ExampleInventoryRead() {}
private static void parseArgs(String args[]) {
for(int i = 0; i &lt; args.length; ++i) {
if (args[i].startsWith("-")) {
switch(args[i].charAt(1)) {
case 'h':
myDbEnvPath = new File(args[++i]);
break;
case 's':
locateItem = args[++i];
break;
default:
usage();
}
}
}
}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl_exampledatabaseput.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl_example.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="baseapi.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">ExampleDatabasePut.class </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Part II. Programming with the Base API</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,107 @@
<?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>Replacing Entity Objects</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="dpl_delete.html" title="Deleting Entity Objects" />
<link rel="next" href="dpl_example.html" title="Chapter 6. A DPL Example" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Replacing Entity Objects</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl_delete.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl_example.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="dpl_replace"></a>Replacing Entity Objects</h2>
</div>
</div>
<div></div>
</div>
<p>
To modify a stored entity object, retrieve it, update
it, then put it back to the entity store:
</p>
<pre class="programlisting">
SimpleEntityClass sec = sda.pIdx.get("keyone");
sec.setsKey("skeyoneupdated");
sda.pIdx.put(sec);
</pre>
<p>
Note that because we updated a field on the object that is
a secondary key, this object will now be accessible by the
secondary key of <tt class="literal">skeyoneupdated</tt> instead
of the previous value, which was <tt class="literal">skeyone</tt>
</p>
<p>
Be aware that if you modify the object's primary key, the behavior is
somewhat different. In this case, you cause a new instance
of the object to be created in the store, instead of
replacing an existing instance:
</p>
<pre class="programlisting">// Results in two objects in the store. One with a
// primary index of "keyfive" and the other with primary index of
//'keyfivenew'.
SimpleEntityClass sec = sda.pIdx.get("keyfive");
sec.setpKey("keyfivenew");
sda.pIdx.put(sec); </pre>
<p>
Finally, if you are iterating over a collection of objects
using an <tt class="classname">EntityCursor</tt>, you can
update each object in turn using
<tt class="methodname">EntityCursor.update()</tt>. Note,
however, that you must be iterating using a
<tt class="classname">PrimaryIndex</tt>; this operation is not
allowed if you are using a
<tt class="classname">SecondaryIndex</tt>.
</p>
<p>
For example, the following iterates over every
<tt class="classname">SimpleEntityClass</tt> object in the entity
store, and it changes them all so that they have a
secondary index of <tt class="literal">updatedskey</tt>:
</p>
<pre class="programlisting">EntityCursor&lt;SimpleEntityClass&gt; sec_pcursor = sda.pIdx.entities();
for (SimpleEntityClass sec : sec_pcursor) {
sec.setsKey("updatedskey");
sec_pcursor.update(item);
}
sec_pcursor.close(); </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl_delete.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl_example.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Deleting Entity Objects </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 6. A DPL Example</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,406 @@
<?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>Creating Indexes</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_index.html" title="Chapter 4. Working with Indices" />
<link rel="previous" href="persist_index.html" title="Chapter 4. Working with Indices" />
<link rel="next" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Creating Indexes</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="persist_index.html">Prev</a> </td>
<th width="60%" align="center">Chapter 4. Working with Indices</th>
<td width="20%" align="right"> <a accesskey="n" href="persist_access.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="dplindexcreate"></a>Creating Indexes</h2>
</div>
</div>
<div></div>
</div>
<p>
To create an index using the DPL, you use Java
annotations to declare which feature on the class is used
for the primary index, and which features (if any) are to
be used as secondary indexes.
</p>
<p>
All entity classes stored in the DPL must have a
primary index declared for it.
</p>
<p>
Entity classes can have zero or more secondary
indexes declared for them. There is no limit on the
number of secondary indexes that you can declare.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="dplprimaryidxdecl"></a>Declaring a Primary Indexes</h3>
</div>
</div>
<div></div>
</div>
<p>
You declare a primary key for an entity class by
using the <tt class="literal">@PrimaryKey</tt>
annotation. This annotation must appear
immediately before the data member which
represents the class's primary key. For example:
</p>
<pre class="programlisting">package persist.gettingStarted;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.PrimaryKey;
@Entity
public class Vendor {
private String address;
private String bizPhoneNumber;
private String city;
private String repName;
private String repPhoneNumber;
private String state;
// Primary key is the vendor's name
// This assumes that the vendor's name is
// unique in the database.
@PrimaryKey
private String vendor;
... </pre>
<p>
For this class, the <tt class="literal">vendor</tt> value is set for an individual
<tt class="classname">Vendor</tt> class object by
the <tt class="methodname">setVendorName()</tt>
method. If our example code fails to set this
value before storing the object, the data
member used to store the primary key is set to a
null value. This would result in a runtime
error.
</p>
<p>
You can avoid the need to explicitly set a
value for a class's primary index by specifying
a sequence to be used for the primary key. This
results in an unique integer value being used
as the primary key for each stored object.
</p>
<p>
You declare a sequence is to be used by specifying
the <tt class="literal">sequence</tt> keyword to the
<tt class="literal">@PrimaryKey</tt> annotation.
For example:
</p>
<pre class="programlisting">@PrimaryKey(sequence="")
long myPrimaryKey; </pre>
<p>
If you provide the <tt class="literal">sequence</tt> keyword with a name,
then the sequence is obtained from that named sequence. For example:
</p>
<pre class="programlisting">@PrimaryKey(sequence="Sequence_Namespace")
long myPrimaryKey; </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="dplsecondaryidxdecl"></a>Declaring Secondary Indexes</h3>
</div>
</div>
<div></div>
</div>
<p>
To declare a secondary index, we use the
<tt class="literal">@SecondaryKey</tt> annotation. Note
that when we do this, we must declare what sort of
an index it is; that is, what is its relationship to
other data in the data store.
</p>
<p>
The <span class="emphasis"><em>kind</em></span> of indices that we
can declare are:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="literal">ONE_TO_ONE</tt>
</p>
<p>
This relationship indicates that
the secondary key is unique to the
object. If an object is stored with a
secondary key that already
exists in the data store, a run
time error is raised.
</p>
<p>
For example, a person object might
be stored with a primary key of a
social security number (in the US),
with a secondary key of the
person's employee number. Both
values are expected to be unique in
the data store.
</p>
</li>
<li>
<p>
<tt class="literal">MANY_TO_ONE</tt>
</p>
<p>
Indicates that the secondary key
may be used for multiple
objects in the data store. That is,
the key appears more than
once, but for each stored object it
can be used only once.
</p>
<p>
Consider a data store that relates
managers to employees. A given
manager will have multiple
employees, but each employee is
assumed to have just one manager.
In this case, the manager's
employee number might be a
secondary key, so that you can
quickly locate all the objects
related to that manager's
employees.
</p>
</li>
<li>
<p>
<tt class="literal">ONE_TO_MANY</tt>
</p>
<p>
Indicates that the secondary key
might be used more than once for a
given object. Index keys
themselves are assumed to be
unique, but multiple instances of
the index can be used per object.
</p>
<p>
For example, employees might have
multiple unique email addresses. In
this case, any given object can be
access by one or more email
addresses. Each such address is
unique in the data store, but each
such address will relate to a
single employee object.
</p>
</li>
<li>
<p>
<tt class="literal">MANY_TO_MANY</tt>
</p>
<p>
There can be multiple keys for
any given object, and for any given
key there can be many related
objects.
</p>
<p>
For example, suppose your
organization has a shared
resource, such as printers. You
might want to track which
printers a given employee can
use (there might be more than
one). You might also want to
track which employees can use a
specific printer. This
represents a many-to-many
relationship.
</p>
</li>
</ul>
</div>
<p>
Note that for <tt class="literal">ONE_TO_ONE</tt> and
<tt class="literal">MANY_TO_ONE</tt> relationships, you
need a simple data member (not an array or
collection) to hold the key. For
<tt class="literal">ONE_TO_MANY</tt> and
<tt class="literal">MANY_TO_MANY</tt> relationships, you
need an array or collection to hold the keys:
</p>
<pre class="programlisting">@SecondaryKey(relate=ONE_TO_ONE)
private String primaryEmailAddress = new String();
@SecondaryKey(relate=ONE_TO_MANY)
private Set&lt;String&gt; emailAddresses = new HashSet&lt;String&gt;(); </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="foreignkey"></a>Foreign Key Constraints</h3>
</div>
</div>
<div></div>
</div>
<p>
Sometimes a secondary index is related in some
way to another entity class that is also
contained in the data store. That is, the
secondary key might be the primary key for
another entity class. If this is the case, you
can declare the foreign key constraint to make
data integrity easier to accomplish.
</p>
<p>
For example, you might have one class that is
used to represent employees.
You might have another that is used to
represent corporate divisions. When you add or
modify an employee record, you might want to
ensure that the division to which the employee
belongs is known to the data store. You do this
by specifying a foreign key constraint.
</p>
<p>
When a foreign key constraint is declared:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
When a new secondary key
for the object is stored,
it is checked to make sure
it exists as a primary
key for the related
entity object. If it does
not, a runtime error
occurs.
</p>
</li>
<li>
<p>
When a related entity is
deleted (that is, a
corporate division is
removed from the data
store), some action is
automatically taken for
the entities that refer to
this object (that is, the
employee objects). Exactly
what that action is, is
definable by you. See
below.
</p>
</li>
</ul>
</div>
<p>
When a related entity is deleted from the data
store, one of the following actions are taken:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="literal">ABORT</tt>
</p>
<p>
The delete operation is not
allowed. A runtime error is
raised as a result of the
operation. This is the
default behavior.
</p>
</li>
<li>
<p>
<tt class="literal">CASCADE</tt>
</p>
<p>
All entities related to this
one are deleted as well. For
example, if you deleted a
<tt class="classname">Division</tt>
object, then all
<tt class="classname">Employee</tt>
objects that belonged to the
division are also deleted.
</p>
</li>
<li>
<p>
<tt class="literal">NULLIFY</tt>
</p>
<p>
All entities related to the
deleted entity are updated so
that the pertinent data member
is nullified. That is, if you
deleted a division, then all
employee objects related to
that division would have their
division key
automatically set to null.
</p>
</li>
</ul>
</div>
<p>
You declare a foreign key constraint by using
the <tt class="literal">relatedEntity</tt> keyword. You
declare the foreign key constraint deletion policy using the
<tt class="literal">onRelatedEntityDelete</tt> keyword. For
example, the following declares a foreign key
constraint to <tt class="classname">Division</tt>
class objects, and it causes related objects to
be deleted if the <tt class="classname">Division</tt>
class is deleted:
</p>
<pre class="programlisting">@SecondaryKey(relate=ONE_TO_ONE, relatedEntity=Division.class,
onRelatedEntityDelete=CASCADE)
private String division = new String(); </pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="persist_index.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_index.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="persist_access.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 4. Working with Indices </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 5. Saving and Retrieving Objects</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,151 @@
<?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>Environments</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="databaseLimits.html" title="Database Limits and Portability" />
<link rel="next" href="coreExceptions.html" title="Exception Handling" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Environments</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="databaseLimits.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="coreExceptions.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="environments"></a>Environments</h2>
</div>
</div>
<div></div>
</div>
<p>
This manual is meant as an introduction to the Berkeley DB library.
Consequently, it describes how to build a very simple, single-threaded
application. Consequently, this manual omits a great many powerful
aspects of the DB database engine that are not required by simple
applications. One of these is important enough that it warrants a brief
overview here: environments.
</p>
<p>
While environments are frequently not used by applications running in
embedded environments where every byte counts, they will be used by
virtually any other DB application requiring anything other than
the bare minimum functionality. An <span class="emphasis"><em>environment</em></span> is
essentially an encapsulation of one or more databases. Essentially, you
open an environment and then you open databases in that environment.
When you do so, the databases are created/located in a location relative
to the environment's home directory.
</p>
<p>
Environments offer a great many features that a stand-alone DB
database cannot offer:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Multi-database files.
</p>
<p>
It is possible in DB to contain multiple databases in a
single physical file on disk. This is desirable for those
application that open more than a few handful of databases.
However, in order to have more than one database contained in
a single physical file, your application
<span class="emphasis"><em>must</em></span> use an environment.
</p>
</li>
<li>
<p>
Multi-thread and multi-process support
</p>
<p>
When you use an environment, resources such as the in-memory
cache and locks can be shared by all of the databases opened in the
environment. The environment allows you to enable
subsystems that are designed to allow multiple threads and/or
processes to access DB databases. For example, you use an
environment to enable the concurrent data store (CDS), the
locking subsystem, and/or the shared memory buffer pool.
</p>
</li>
<li>
<p>
Transactional processing
</p>
<p>
DB offers a transactional subsystem that allows for full
ACID-protection of your database writes. You use environments to
enable the transactional subsystem, and then subsequently to obtain
transaction IDs.
</p>
</li>
<li>
<p>
High availability (replication) support
</p>
<p>
DB offers a replication subsystem that enables
single-master database replication with multiple read-only
copies of the replicated data. You use environments to enable
and then manage this subsystem.
</p>
</li>
<li>
<p>
Logging subsystem
</p>
<p>
DB offers write-ahead logging for applications that want to
obtain a high-degree of recoverability in the face of an
application or system crash. Once enabled, the logging subsystem
allows the application to perform two kinds of recovery
("normal" and "catastrophic") through the use of the information
contained in the log files.
</p>
</li>
</ul>
</div>
<p>
For more information on these topics, see the
<i class="citetitle">Berkeley DB Getting Started with Transaction Processing</i> guide and the
<i class="citetitle">Berkeley DB Getting Started with Replicated Applications</i> guide.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="databaseLimits.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="coreExceptions.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Database Limits and Portability </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Exception Handling</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,317 @@
<?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>Retrieving Multiple Objects</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="simpleget.html" title="Retrieving Objects from an Entity Store" />
<link rel="next" href="dpl_entityjoin.html" title="Join Cursors" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Retrieving Multiple Objects</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="simpleget.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="dpl_entityjoin.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="getmultiple"></a>Retrieving Multiple Objects</h2>
</div>
</div>
<div></div>
</div>
<p>
It is possible to iterate over every object referenced
by a specific index. You may want to do this if, for
example, you want to examine or modify every object
accessible by a specific primary index.
</p>
<p>
In addition, some indexes result in the retrieval of multiple
objects. For example, <tt class="literal">MANY_TO_ONE</tt>
secondary indexes can result in more than one object for any given
key (also known as <span class="emphasis"><em>duplicate keys</em></span>).
When this is the case, you must iterate
over the resulting set of objects in order to examine
each object in turn.
</p>
<p>
There are two ways to iterate over a collection of
objects as returned by an index. One is to use a
standard Java <tt class="classname">Iterator</tt>, which you
obtain using an <tt class="classname">EntityCursor</tt>,
which in turn you can obtain from a <tt class="classname">PrimaryIndex</tt>:
</p>
<pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
store.getPrimaryIndex(String.class, SimpleEntityClass.class);
EntityCursor&lt;SimpleEntityClass&gt; pi_cursor = pi.entities();
try {
Iterator&lt;SimpleEntityClass&gt; i = pi_cursor.iterator();
while (i.hasNext()) {
// Do something here
}
} finally {
// Always close the cursor
pi_cursor.close();
} </pre>
<p>
Alternatively, you can use a Java "foreach" statement
to iterate over object set:
</p>
<pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
store.getPrimaryIndex(String.class, SimpleEntityClass.class);
EntityCursor&lt;SimpleEntityClass&gt; pi_cursor = pi.entities();
try {
for (SimpleEntityClass seci : pi_cursor) {
// do something with each object "seci"
}
// Always make sure the cursor is closed when we are done with it.
} finally {
sec_cursor.close();
} </pre>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="dpl_cursor_initialize"></a>Cursor Initialization</h3>
</div>
</div>
<div></div>
</div>
<p>
When a cursor is first opened, it is not
positioned to any value; that is,
it is not <span class="emphasis"><em>initialized</em></span>.
Most of the <tt class="classname">EntityCursor</tt>
methods that move a cursor will initialize it
to either the first or last object, depending
on whether the operation is moving the cursor
forward (all <tt class="literal">next...</tt>
methods) or backwards (all
<tt class="literal">prev...</tt>) methods.
</p>
<p>
You can also force a cursor, whether it is
initialized or not, to return the first object
by calling
<tt class="methodname">EntityCursor.first()</tt>.
Similarly, you can force a return of the last
object using
<tt class="methodname">EntityCursor.last()</tt>.
</p>
<p>
Operations that do not move the cursor (such as
<tt class="methodname">EntityCursor.current()</tt>
or <tt class="methodname">EntityCursor.delete()</tt>
will throw an
<tt class="classname">IllegalStateException</tt>
when used on an uninitialized cursor.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="dpl_dups"></a>Working with Duplicate Keys</h3>
</div>
</div>
<div></div>
</div>
<p>
If you have duplicate secondary keys, you can return an
<tt class="classname">EntityIndex</tt> class object for them
using <tt class="methodname">SecondaryIndex.subIndex()</tt>
Then, use that object's
<tt class="methodname">entities()</tt>
method to obtain an <tt class="classname">EntityCursor</tt>
instance.
</p>
<p>
For example:
</p>
<pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
store.getPrimaryIndex(String.class, SimpleEntityClass.class);
SecondaryIndex&lt;String,String,SimpleEntityClass&gt; si =
store.getSecondaryIndex(pi, String.class, "sKey");
EntityCursor&lt;SimpleEntityClass&gt; sec_cursor =
si.subIndex("skeyone").entities();
try {
for (SimpleEntityClass seci : sec_cursor) {
// do something with each object "seci"
}
// Always make sure the cursor is closed when we are done with it.
} finally {
sec_cursor.close(); } </pre>
<p>
Note that if you are working with duplicate keys, you can
control how cursor iteration works by using the following
<tt class="classname">EntityCursor</tt> methods:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">nextDup()</tt>
</p>
<p>
Moves the cursor to the next object with the
same key as the cursor is currently
referencing. That is, this method returns the
next duplicate object. If no such object
exists, this method returns
<tt class="literal">null</tt>.
</p>
</li>
<li>
<p>
<tt class="methodname">prevDup()</tt>
</p>
<p>
Moves the cursor to the previous object with the
same key as the cursor is currently
referencing. That is, this method returns the
previous duplicate object in the cursor's set
of objects. If no such object exists, this method returns
<tt class="literal">null</tt>.
</p>
</li>
<li>
<p>
<tt class="methodname">nextNoDup()</tt>
</p>
<p>
Moves the cursor to the next object in the
cursor's set that has a key which is different
than the key that the cursor is currently
referencing. That is, this method skips all
duplicate objects and returns the
next non-duplicate object in the cursor's set
of objects. If no such object exists, this method returns
<tt class="literal">null</tt>.
</p>
</li>
<li>
<p>
<tt class="methodname">prevNoDup()</tt>
</p>
<p>
Moves the cursor to the previous object in the
cursor's set that has a key which is different
than the key that the cursor is currently
referencing. That is, this method skips all
duplicate objects and returns the
previous non-duplicate object in the cursor's set
of objects. If no such object exists, this method returns
<tt class="literal">null</tt>.
</p>
</li>
</ul>
</div>
<p>
For example:
</p>
<pre class="programlisting">PrimaryIndex&lt;String,SimpleEntityClass&gt; pi =
store.getPrimaryIndex(String.class, SimpleEntityClass.class);
SecondaryIndex&lt;String,String,SimpleEntityClass&gt; si =
store.getSecondaryIndex(pi, String.class, "sKey");
EntityCursor&lt;SimpleEntityClass&gt; sec_cursor =
si.subIndex("skeyone").entities();
try {
Iterator&lt;SimpleEntityClass&gt; i = sec_cursor.iterator();
while (i.nextNoDup()) {
// Do something here
}
// Always make sure the cursor is closed when we are done with it.
} finally {
sec_cursor.close(); } </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="dpl_cursor_range"></a>Key Ranges</h3>
</div>
</div>
<div></div>
</div>
<p>
You can restrict the scope of a cursor's movement
by specifying a <span class="emphasis"><em>range</em></span> when you
create the cursor. The cursor can then never be
positioned outside of the specified range.
</p>
<p>
When specifying a range, you indicate whether a
range bound is <span class="emphasis"><em>inclusive</em></span> or
<span class="emphasis"><em>exclusive</em></span> by providing a
boolean value for each range.
<tt class="literal">true</tt> indicates that the provided
bound is inclusive, while <tt class="literal">false</tt>
indicates that it is exclusive.
</p>
<p>
You provide this information when you call
<tt class="classname">PrimaryIndex.entities()</tt>
or
<tt class="classname">SecondaryIndex.entities()</tt>.
For example, suppose you had a class indexed by
numerical information. Suppose further that you
wanted to examine only those objects with indexed
values of 100 - 199. Then (assuming the numerical
information is the primary index), you can bound
your cursor as follows:
</p>
<pre class="programlisting">
EntityCursor&lt;SomeEntityClass&gt; cursor =
primaryIndex.entities(100, true, 200, false);
try {
for (SomeEntityClass sec : cursor {
// Do something here to objects ranged from 100 to 199
}
// Always make sure the cursor is closed when we are done with it.
} finally {
cursor.close(); } </pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="simpleget.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dpl_entityjoin.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Retrieving Objects from an Entity Store </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Join Cursors</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,41 @@
body { width: 45em;
margin-left: 3em;
font-family: Arial, Helvetica, sans-serif;
font-size: 11pt;
}
h2.title { margin-left: -1em;
font-family: Verdana, serif;
font-size: 16pt;
}
h3.title { font-family: Verdana, serif;
font-size: 14pt;
}
pre.programlisting {
font-family: monospace;
background-color: #eae8e9;
}
div.navheader { font-size: 9pt;
width: 60em;
margin-left: -2em;
}
div.navheader table tr td { font-size: 9pt; }
div.navfooter { font-size: 9pt;
width: 60em;
margin-left: -2em;
}
div.navfooter table tr td { font-size: 9pt; }
span.emphasis { font-style: italic; font-size: 9pt;}
div.appendix div.informaltable { font-size: 9pt; }
div.appendix div.informaltable td { vertical-align: top; }
div.appendix div.informaltable p { margin-top: .25em; }
div.appendix div.informaltable p { margin-bottom: .25em; }

View File

@@ -0,0 +1,77 @@
<?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>Getting and Using DB </title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="returns.html" title="Error Returns" />
<link rel="next" href="Env.html" title="Chapter 2. Database Environments" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Getting and Using DB </th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="returns.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="Env.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="gettingit"></a>Getting and Using DB </h2>
</div>
</div>
<div></div>
</div>
<p>
You can obtain DB by visiting the Berkeley DB download page:
<a href="http://www.oracle.com/technology/software/products/berkeley-db/db/index.html" target="_top">http://www.oracle.com/technology/software/products/berkeley-db/db/index.html</a>.
</p>
<p>
To install DB, untar or unzip the distribution to the directory of
your choice. You will then need to build the product binaries.
For information on building DB, see
<span class="emphasis"><em>DB_INSTALL</em></span><tt class="literal">/docs/index.html</tt>,
where <span class="emphasis"><em>DB_INSTALL</em></span> is the directory where you unpacked
DB. On that page, you will find links to platform-specific build
instructions.
</p>
<p>
That page also contains links to more documentation for DB. In
particular, you will find links for the
<i class="citetitle">Berkeley DB Programmer's Reference Guide</i>
as well as the API reference documentation.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="returns.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="Env.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Error Returns </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 2. Database Environments</td>
</tr>
</table>
</div>
</body>
</html>

812
docs/gsg/JAVA/index.html Normal file
View File

@@ -0,0 +1,812 @@
<?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>Getting Started with Berkeley DB</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="next" href="preface.html" title="Preface" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Getting Started with Berkeley DB</th>
</tr>
<tr>
<td width="20%" align="left"> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="preface.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="book" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a id="id613798"></a>Getting Started with Berkeley DB</h1>
</div>
<div>
<div class="legalnotice">
<p class="legalnotice-title">
<b>Legal Notice</b>
</p>
<p>
This documentation is distributed under an open source license.
You may review the terms of this license at:
<a href="http://www.oracle.com/technology/software/products/berkeley-db/htdocs/oslicense.html" target="_top">http://www.oracle.com/technology/software/products/berkeley-db/htdocs/oslicense.html</a>
</p>
<p>
Oracle, Berkeley DB,
and
Sleepycat are trademarks or registered trademarks of
Oracle. All rights to these marks are reserved.
No third-party use is permitted without the
express prior written consent of Oracle.
</p>
<p>
<span class="trademark">Java</span>™ and all Java-based marks are a trademark
or registered trademark of Sun Microsystems,
Inc, in the United States and other countries.
</p>
<p>
To obtain a copy of this document's original source code, please
submit a request to the Oracle Technology Network forum at:
<a href="http://forums.oracle.com/forums/forum.jspa?forumID=271" target="_top">http://forums.oracle.com/forums/forum.jspa?forumID=271</a>
</p>
</div>
</div>
<div>
<p class="pubdate">4/25/2008</p>
</div>
</div>
<div></div>
<hr />
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="preface">
<a href="preface.html">Preface</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="preface.html#conventions">Conventions Used in this Book</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="preface.html#moreinfo">For More Information</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="introduction.html">1. Introduction to Berkeley DB </a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="introduction.html#aboutthismanual">About This Manual</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="javadplconcepts.html">Berkeley DB Concepts</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#dplenvconcepts">Environments</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#key-data">Key-Data Pairs</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#storing-intro">Storing Data</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#duplicatesintro">Duplicate Data</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#replacedeleteIntro">Replacing and Deleting Entries</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#secondary">Secondary Keys</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#whichapi">Which API Should You Use?</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="accessmethods.html">Access Methods</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="accessmethods.html#selectAM">Selecting Access Methods</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="accessmethods.html#BTreeVSHash">Choosing between BTree and Hash</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="accessmethods.html#QueueVSRecno">Choosing between Queue and Recno</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="databaseLimits.html">Database Limits and Portability</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="coreExceptions.html">Exception Handling</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="returns.html">Error Returns</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="gettingit.html">Getting and Using DB </a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="Env.html">2. Database Environments</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="Env.html#EnvOpen">Opening Database Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="EnvClose.html">Closing Database Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="EnvProps.html">Environment Properties</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="EnvProps.html#envconfig">The EnvironmentConfig Class</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="EnvProps.html#envhandleconfig">EnvironmentMutableConfig</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="part">
<a href="dpl.html">I. Programming with the Direct Persistence Layer</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="chapter">
<a href="persist_first.html">3. Direct Persistence Layer First Steps</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="persist_first.html#entitystore">Entity Stores</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="persist_first.html#persist-open">Opening and Closing Environments and Stores</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="persistobject.html">Persistent Objects</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="saveret.html">Saving a Retrieving Data</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="persist_index.html">4. Working with Indices</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="persist_index.html#dplindexaccess">Accessing Indexes</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="persist_index.html#primaryindexaccess">Accessing Primary Indices</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="persist_index.html#secondaryindexaccess">Accessing Secondary Indices</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dplindexcreate.html">Creating Indexes</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#dplprimaryidxdecl">Declaring a Primary Indexes</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#dplsecondaryidxdecl">Declaring Secondary Indexes</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#foreignkey">Foreign Key Constraints</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="persist_access.html">5. Saving and Retrieving Objects</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="persist_access.html#simpleentity">A Simple Entity Class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleda.html">SimpleDA.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleput.html">Placing Objects in an Entity Store</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleget.html">Retrieving Objects from an Entity Store</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="getmultiple.html">Retrieving Multiple Objects</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_cursor_initialize">Cursor Initialization</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_dups">Working with Duplicate Keys</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_cursor_range">Key Ranges</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dpl_entityjoin.html">Join Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_delete.html">Deleting Entity Objects</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_replace.html">Replacing Entity Objects</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="dpl_example.html">6. A DPL Example</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="dpl_example.html#vendorclass">Vendor.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="inventoryclass.html">Inventory.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="mydbenv-persist.html">MyDbEnv</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dataaccessorclass.html">DataAccessor.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_exampledatabaseput.html">ExampleDatabasePut.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_exampleinventoryread.html">ExampleInventoryRead.class</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="part">
<a href="baseapi.html">II. Programming with the Base API</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="chapter">
<a href="DB.html">7. Databases</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="DB.html#DBOpen">Opening Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="coredbclose.html">Closing Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DBConfig.html">Database Properties</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DBAdmin.html">Administrative Methods</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dbErrorReporting.html">Error Reporting Functions</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="CoreEnvUsage.html">Managing Databases in Environments</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="CoreJavaUsage.html">Database Example</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="DBEntry.html">8. Database Records</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="DBEntry.html#usingDbEntry">Using Database Records</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="usingDbt.html">Reading and Writing Database Records</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="usingDbt.html#databaseWrite">Writing Records to the Database</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#databaseRead">Getting Records from the Database</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#recordDelete">Deleting Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="usingDbt.html#datapersist">Data Persistence</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="bindAPI.html">Using the BIND APIs</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="bindAPI.html#bindPrimitive">Numerical and String Objects</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="bindAPI.html#object2dbt">Serializable Complex Objects</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="bindAPI.html#customTuple">Custom Tuple Bindings</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dbtJavaUsage.html">Database Usage Example</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="Cursors.html">9. Using Cursors</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="Cursors.html#openCursor">Opening and Closing Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="Positioning.html">Getting Records Using the Cursor</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="Positioning.html#cursorsearch">Searching for Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="Positioning.html#getdups">Working with Duplicate Records</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="PutEntryWCursor.html">Putting Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="DeleteEntryWCursor.html">Deleting Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="ReplacingEntryWCursor.html">Replacing Records Using Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="cursorJavaUsage.html">Cursor Example</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="indexes.html">10. Secondary Databases</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="indexes.html#DbAssociate">Opening and Closing Secondary Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="keyCreator.html">Implementing Key
Creators
</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="keyCreator.html#multikeys">Working with Multiple Keys</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="secondaryProps.html">Secondary Database Properties</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="readSecondary.html">Reading Secondary Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="secondaryDelete.html">Deleting Secondary Database Records</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="secondaryCursor.html">
Using Secondary Cursors
</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="joins.html">Database Joins</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="joins.html#joinUsage">Using Join Cursors</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="joins.html#joinconfig">JoinCursor Properties</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="javaindexusage.html">Secondary Database Example</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="javaindexusage.html#secondaryMyDbs">Opening Secondary Databases with MyDbs</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javaindexusage.html#exampleReadJavaSecondaries">Using Secondary Databases with ExampleDatabaseRead</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
<dt>
<span class="chapter">
<a href="dbconfig.html">11. Database Configuration</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect1">
<a href="dbconfig.html#pagesize">Setting the Page Size</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="dbconfig.html#overflowpages">Overflow Pages</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#Locking">Locking</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#IOEfficiency">IO Efficiency</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dbconfig.html#pagesizeAdvice">Page Sizing Advice</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="cachesize.html">Selecting the Cache Size</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="btree.html">BTree Configuration</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="btree.html#duplicateRecords">Allowing Duplicate Records</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="btree.html#comparators">Setting Comparison Functions</a>
</span>
</dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
</div>
<div class="list-of-examples">
<p>
<b>List of Examples</b>
</p>
<dl>
<dt>7.1. <a href="CoreJavaUsage.html#MyDb">MyDbs Class</a></dt>
<dt>8.1. <a href="dbtJavaUsage.html#inventoryjava">Inventory.java</a></dt>
<dt>8.2. <a href="dbtJavaUsage.html#vendorjava">Vendor.java</a></dt>
<dt>8.3. <a href="dbtJavaUsage.html#InventoryJavaBinding">InventoryBinding.java</a></dt>
<dt>8.4. <a href="dbtJavaUsage.html#dbsStoredClass">Stored Class Catalog Management with MyDbs</a></dt>
<dt>8.5. <a href="dbtJavaUsage.html#EDL">ExampleDatabaseLoad.java</a></dt>
<dt>9.1. <a href="cursorJavaUsage.html#EDR">ExampleDatabaseRead.java</a></dt>
<dt>10.1. <a href="javaindexusage.html#ItemNameKeyCreator-Java">ItemNameKeyCreator.java</a></dt>
<dt>10.2. <a href="javaindexusage.html#mydbsSecondary">SecondaryDatabase Management with MyDbs</a></dt>
<dt>10.3. <a href="javaindexusage.html#secondaryWithEDR">SecondaryDatabase usage with ExampleDatabaseRead</a></dt>
</dl>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="preface.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top"> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right" valign="top"> Preface</td>
</tr>
</table>
</div>
</body>
</html>

395
docs/gsg/JAVA/indexes.html Normal file
View File

@@ -0,0 +1,395 @@
<?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>Chapter 10. Secondary Databases</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="baseapi.html" title="Part II. Programming with the Base API" />
<link rel="previous" href="cursorJavaUsage.html" title="Cursor Example" />
<link rel="next" href="keyCreator.html" title="Implementing Key &#10; Creators&#10; &#10; " />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 10. Secondary Databases</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="cursorJavaUsage.html">Prev</a> </td>
<th width="60%" align="center">Part II. Programming with the Base API</th>
<td width="20%" align="right"> <a accesskey="n" href="keyCreator.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="indexes"></a>Chapter 10. Secondary Databases</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="indexes.html#DbAssociate">Opening and Closing Secondary Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="keyCreator.html">Implementing Key
Creators
</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="keyCreator.html#multikeys">Working with Multiple Keys</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="secondaryProps.html">Secondary Database Properties</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="readSecondary.html">Reading Secondary Databases</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="secondaryDelete.html">Deleting Secondary Database Records</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="secondaryCursor.html">
Using Secondary Cursors
</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="joins.html">Database Joins</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="joins.html#joinUsage">Using Join Cursors</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="joins.html#joinconfig">JoinCursor Properties</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="javaindexusage.html">Secondary Database Example</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="javaindexusage.html#secondaryMyDbs">Opening Secondary Databases with MyDbs</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javaindexusage.html#exampleReadJavaSecondaries">Using Secondary Databases with ExampleDatabaseRead</a>
</span>
</dt>
</dl>
</dd>
</dl>
</div>
<p>
Usually you find database records by means of the record's key. However,
the key that you use for your record will not always contain the
information required to provide you with rapid access to the data that you
want to retrieve. For example, suppose your
<tt class="classname">Database</tt>
contains records related to users. The key might be a string that is some
unique identifier for the person, such as a user ID. Each record's data,
however, would likely contain a complex object containing details about
people such as names, addresses, phone numbers, and so forth.
While your application may frequently want to query a person by user
ID (that is, by the information stored in the key), it may also on occasion
want to locate people by, say, their name.
</p>
<p>
Rather than iterate through all of the records in your database, examining
each in turn for a given person's name, you create indexes based on names
and then just search that index for the name that you want. You can do this
using secondary databases. In DB, the
<tt class="classname">Database</tt>
that contains your data is called a
<span class="emphasis"><em>primary database</em></span>. A database that provides an
alternative set of keys to access that data is called a <span class="emphasis"><em>secondary
database</em></span> In a secondary database, the keys are your alternative
(or secondary) index, and the data corresponds to a primary record's key.
</p>
<p>
You create a secondary database by using a <tt class="classname">SecondaryConfig</tt>
class object to identify an implementation of a
<tt class="classname">SecondaryKeyCreator</tt>
class object that is used to create keys based on data found in the primary
database. You then pass this <tt class="classname">SecondaryConfig</tt>
object to the <tt class="classname">SecondaryDatabase</tt> constructor.
</p>
<p>
Once opened, DB manages secondary databases for you. Adding or deleting
records in your primary database causes DB to update the secondary as
necessary. Further, changing a record's data in the primary database may cause
DB to modify a record in the secondary, depending on whether the change
forces a modification of a key in the secondary database.
</p>
<p>
Note that you can not write directly to a secondary database.
To change the data referenced by a
<tt class="classname">SecondaryDatabase</tt>
record, modify the primary database instead. The exception to this rule is
that delete operations are allowed on the
<span><tt class="classname">SecondaryDatabase</tt> object.</span>
See <a href="secondaryDelete.html">Deleting Secondary Database Records</a> for more
information.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
Secondary database records are updated/created by DB
only if the
<span><tt class="methodname">SecondaryKeyCreator.createSecondaryKey()</tt> method</span>
returns
<span><tt class="literal">true</tt>.</span>
If
<tt class="literal">false</tt>
is returned, then DB will not add the key to the secondary database, and
in the event of a record update it will remove any existing key.
</p>
<p>
See <a href="keyCreator.html">Implementing Key
<span>Creators</span>
</a> for more
<span>information on this interface and method.</span>
</p>
</div>
<p>
When you read a record from a secondary database, DB automatically
returns
<span>the data and optionally the key</span>
from the corresponding record in the primary database.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="DbAssociate"></a>Opening and Closing Secondary Databases</h2>
</div>
</div>
<div></div>
</div>
<p>
You manage secondary database opens and closes using the
<span>
<tt class="classname">SecondaryDatabase</tt> constructor.
</span>
Just as is the case with primary databases, you must provide
<span>
the <tt class="classname">SecondaryDatabase()</tt> constructor
</span>
with the database's
name and, optionally, other properties such as whether duplicate
records are allowed, or whether the secondary database can be created on
open. In addition, you must also provide:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>A handle to the primary database that this secondary database is
indexing. Note that this means that secondary databases are maintained
only for the specified <tt class="classname">Database</tt> handle. If you
open the same <tt class="classname">Database</tt> multiple times for write
(such as might occur when opening a database for read-only and read-write in the same application),
then you should open the <tt class="classname">SecondaryDatabase</tt> for
each such <tt class="classname">Database</tt> handle.</p>
</li>
<li>
<p>A <tt class="classname">SecondaryConfig</tt> object that provides
properties specific to a secondary database. The most important of
these is used to identify the key creator for the database. The key
creator is responsible for generating keys for the secondary database.
See <a href="secondaryProps.html">Secondary Database Properties</a> for details.</p>
</li>
</ul>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
Primary databases <span class="emphasis"><em>must not</em></span> support duplicate records.
Secondary records point to primary records using the primary key, so that key must be unique.
</p>
</div>
<p>So to open (create) a secondary database, you:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Open your primary database.</p>
</li>
<li>
<p>Instantiate your key creator.</p>
</li>
<li>
<p>Instantiate your <tt class="classname">SecondaryConfig</tt> object.</p>
</li>
<li>
<p>Set your key creator object on your <tt class="classname">SecondaryConfig</tt>
object.</p>
</li>
<li>
<p>Open your secondary database, specifying your primary database
and your <tt class="classname">SecondaryConfig</tt> at that time.</p>
</li>
</ol>
</div>
<p>For example:</p>
<a id="java_index1"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseType;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.SecondaryDatabase;
import com.sleepycat.db.SecondaryConfig;
import java.io.FileNotFoundException;
...
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(true);
myDbConfig.setType(DatabaseType.BTREE);
SecondaryConfig mySecConfig = new SecondaryConfig();
mySecConfig.setAllowCreate(true);
mySecConfig.setType(DatabaseType.BTREE);
// Duplicates are frequently required for secondary databases.
mySecConfig.setSortedDuplicates(true);
// Open the primary
Database myDb = null;
SecondaryDatabase mySecDb = null;
try {
String dbName = "myPrimaryDatabase";
myDb = new Database(dbName, null, myDbConfig);
// A fake tuple binding that is not actually implemented anywhere.
// The tuple binding is dependent on the data in use.
// Tuple bindings are described earlier in this manual.
TupleBinding myTupleBinding = new MyTupleBinding();
// Open the secondary.
// Key creators are described in the next section.
FullNameKeyCreator keyCreator = new FullNameKeyCreator(myTupleBinding);
// Get a secondary object and set the key creator on it.
mySecConfig.setKeyCreator(keyCreator);
// 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 ...
}</pre>
<p>To close a secondary database, call its close() method. Note that
for best results, you should close all the secondary databases associated
with a primary database before closing the primary.</p>
<p>For example:</p>
<a id="java_index2"></a>
<pre class="programlisting">try {
if (mySecDb != null) {
mySecDb.close();
}
if (myDb != null) {
myDb.close();
}
} catch (DatabaseException dbe) {
// Exception handling goes here
}</pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="cursorJavaUsage.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="baseapi.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="keyCreator.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Cursor Example </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Implementing Key
Creators
</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,289 @@
<?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>Chapter 1. Introduction to Berkeley DB </title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="previous" href="preface.html" title="Preface" />
<link rel="next" href="javadplconcepts.html" title="Berkeley DB Concepts" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 1. Introduction to Berkeley DB </th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="preface.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="javadplconcepts.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="introduction"></a>Chapter 1. Introduction to Berkeley DB </h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="introduction.html#aboutthismanual">About This Manual</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="javadplconcepts.html">Berkeley DB Concepts</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#dplenvconcepts">Environments</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#key-data">Key-Data Pairs</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#storing-intro">Storing Data</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#duplicatesintro">Duplicate Data</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#replacedeleteIntro">Replacing and Deleting Entries</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#secondary">Secondary Keys</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="javadplconcepts.html#whichapi">Which API Should You Use?</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="accessmethods.html">Access Methods</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="accessmethods.html#selectAM">Selecting Access Methods</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="accessmethods.html#BTreeVSHash">Choosing between BTree and Hash</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="accessmethods.html#QueueVSRecno">Choosing between Queue and Recno</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="databaseLimits.html">Database Limits and Portability</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="coreExceptions.html">Exception Handling</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="returns.html">Error Returns</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="gettingit.html">Getting and Using DB </a>
</span>
</dt>
</dl>
</div>
<p>
Welcome to Berkeley DB (DB). DB is a general-purpose embedded
database engine that is capable of providing a wealth of data management services.
It is designed from the ground up for high-throughput applications requiring
in-process, bullet-proof management of mission-critical data. DB can
gracefully scale from managing a few bytes to terabytes of data. For the most
part, DB is limited only by your system's available physical resources.
</p>
<p>
You use DB through a series of Java APIs which give you the
ability to read and write your data, manage your database(s), and
perform other more advanced activities such as managing
transactions.
<span>
The Java APIs that you use to interact with DB
come in two basic flavors. The first is a high-level API that
allows you to make Java classes persistent. The second is a
lower-level API which provides additional flexibility when interacting
with DB databases.
</span>
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
For long-time users of DB, the lower-level API is the
traditional API that you are probably accustomed to using.
</p>
</div>
<p>
Because DB is an embedded database engine, it is extremely fast. You compile
and link it into your application in the same way as you would any
third-party library. This means that DB runs in the same process space
as does your application, allowing you to avoid the high cost of
interprocess communications incurred by stand-alone database servers.
</p>
<p>
To further improve performance, DB offers an in-memory cache designed to
provide rapid access to your most frequently used data. Once configured,
cache usage is transparent. It requires very little attention on the part
of the application developer.
</p>
<p>
Beyond raw speed, DB is also extremely configurable. It provides several
different ways of organizing your data in its databases. Known as
<span class="emphasis"><em>access methods</em></span>, each such data organization mechanism
provides different characteristics that are appropriate for different data
management profiles. (Note that this manual focuses almost entirely on the
BTree access method as this is the access method used by the vast majority
of DB applications).
</p>
<p>
To further improve its configurability, DB offers many different
subsystems, each of which can be used to extend DB's capabilities. For
example, many applications require write-protection of their data so
as to ensure that data is never left in an inconsistent state for any
reason (such as software bugs or hardware failures). For those
applications, a transaction subsystem can be enabled and used to
transactional-protect database writes.
</p>
<p>
The list of operating systems on which DB is available is too long to
detail here. Suffice to say that it is available on all major commercial
operating systems, as well as on many embedded platforms.
</p>
<p>
Finally, DB is available in a wealth of programming languages.
DB is officially supported in C, C++, and Java, but the library is also
available in many other languages, especially scripting languages such as
Perl and Python.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
Before going any further, it is important to mention that DB is not
a relational database (although you could use it to build a relational
database). Out of the box, DB does not provide higher-level features
such as triggers, or a high-level query language such as SQL.
Instead, DB provides just those minimal
APIs required to store and retrieve your data as
efficiently as possible.
</p>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="aboutthismanual"></a>About This Manual</h2>
</div>
</div>
<div></div>
</div>
<p>
This manual introduces DB. As such, this book does not examine
intermediate or advanced features such as threaded library usage or
transactional usage. Instead, this manual provides a step-by-step
introduction to DB's basic concepts and library usage.
</p>
<p>
Specifically, this manual introduces the high-level Java API
(the DPL), as well as the "base" Java API that the DPL
relies upon. Regardless of the API set that you choose to use, there are a
series of concepts and APIs that are common across the product.
This manual starts by providing a high-level examination of
DB. It then describes the APIs you use regardless of the API
set that you choose to use. It then provides information on using the
Direct Persistence Layer (DPL) API, followed by information on using
the more extensive "base" API.
</p>
<p>
Examples are given throughout this book that are designed to illustrate
API usage. At the end of each
<span>chapter or section in this book,</span>
a complete example is given that
is designed to reinforce the concepts covered in that
<span>chapter or section.</span>
In addition to being presented in this book, these final programs are also
available in the DB software distribution. You can find them in
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the
location where you placed your DB distribution.
</p>
<p>
This book uses the Java programming languages for its examples.
Note that versions of this book exist for the C and C++ languages as
well.
</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="preface.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="index.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="javadplconcepts.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Preface </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Berkeley DB Concepts</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,146 @@
<?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>Inventory.class</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl_example.html" title="Chapter 6. A DPL Example" />
<link rel="previous" href="dpl_example.html" title="Chapter 6. A DPL Example" />
<link rel="next" href="mydbenv-persist.html" title="MyDbEnv" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Inventory.class</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl_example.html">Prev</a> </td>
<th width="60%" align="center">Chapter 6. A DPL Example</th>
<td width="20%" align="right"> <a accesskey="n" href="mydbenv-persist.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="inventoryclass"></a>Inventory.class</h2>
</div>
</div>
<div></div>
</div>
<p>
Our example's <tt class="classname">Inventory</tt>
class is much like our <tt class="classname">Vendor</tt>
class in that it is simply used to encapsulate
data. However, in this case we want to be able
to access objects two different ways: by
product SKU and by product name.
</p>
<p>
In our data set, the product SKU is required to be
unique, so we use that as the primary key. The
product name, however, is not a unique value so we
set this up as a secondary key.
</p>
<p>
The class appears as follows in our example:
</p>
<pre class="programlisting">package persist.gettingStarted;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.PrimaryKey;
import static com.sleepycat.persist.model.Relationship.*;
import com.sleepycat.persist.model.SecondaryKey;
@Entity
public class Inventory {
// Primary key is sku
@PrimaryKey
private String sku;
// Secondary key is the itemName
@SecondaryKey(relate=MANY_TO_ONE)
private String itemName;
private String category;
private String vendor;
private int vendorInventory;
private float vendorPrice;
public void setSku(String data) {
sku = data;
}
public void setItemName(String data) {
itemName = data;
}
public void setCategory(String data) {
category = data;
}
public void setVendorInventory(int data) {
vendorInventory = data;
}
public void setVendor(String data) {
vendor = data;
}
public void setVendorPrice(float data) {
vendorPrice = data;
}
public String getSku() {
return sku;
}
public String getItemName() {
return itemName;
}
public String getCategory() {
return category;
}
public int getVendorInventory() {
return vendorInventory;
}
public String getVendor() {
return vendor;
}
public float getVendorPrice() {
return vendorPrice;
}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl_example.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl_example.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="mydbenv-persist.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 6. A DPL Example </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> MyDbEnv</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,504 @@
<?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>Berkeley DB Concepts</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="next" href="accessmethods.html" title="Access Methods" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Berkeley DB Concepts</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="introduction.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="accessmethods.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="javadplconcepts"></a>Berkeley DB Concepts</h2>
</div>
</div>
<div></div>
</div>
<p>
Before continuing, it is useful to describe some of the
concepts you will encounter when building a DB
application.
</p>
<p>
The concepts that you will encounter depend upon the actual API
that you are using. Some of these concepts are common to both
APIs, and so we present those first. Others are only
interesting if you use the DPL, while others apply only to
the base API. We present each of these in turn.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="dplenvconcepts"></a>Environments</h3>
</div>
</div>
<div></div>
</div>
<p>
Environments are required for applications built
using the DPL. They are optional, but very commonly
used, for applications built using the base API.
Therefore, it is worthwhile to begin with them.
</p>
<span>
<p>
An <span class="emphasis"><em>environment</em></span> is
essentially an encapsulation of one or more databases. You
open an environment and then you open databases in that environment.
When you do so, the databases are created/located in a location relative
to the environment's home directory.
</p>
<p>
Environments offer a great many features that a stand-alone DB
database cannot offer:
</p>
<div class="itemizedlist"><ul type="disc"><li><p>
Multi-database files.
</p><p>
It is possible in DB to contain multiple databases in a
single physical file on disk. This is desirable for those
application that open more than a few handful of databases.
However, in order to have more than one database contained in
a single physical file, your application
<span class="emphasis"><em>must</em></span> use an environment.
</p></li><li><p>
Multi-thread and multi-process support
</p><p>
When you use an environment, resources such as the in-memory
cache and locks can be shared by all of the databases opened in the
environment. The environment allows you to enable
subsystems that are designed to allow multiple threads and/or
processes to access DB databases. For example, you use an
environment to enable the concurrent data store (CDS), the
locking subsystem, and/or the shared memory buffer pool.
</p></li><li><p>
Transactional processing
</p><p>
DB offers a transactional subsystem that allows for full
ACID-protection of your database writes. You use environments to
enable the transactional subsystem, and then subsequently to obtain
transaction IDs.
</p></li><li><p>
High availability (replication) support
</p><p>
DB offers a replication subsystem that enables
single-master database replication with multiple read-only
copies of the replicated data. You use environments to enable
and then manage this subsystem.
</p></li><li><p>
Logging subsystem
</p><p>
DB offers write-ahead logging for applications that want to
obtain a high-degree of recoverability in the face of an
application or system crash. Once enabled, the logging subsystem
allows the application to perform two kinds of recovery
("normal" and "catastrophic") through the use of the information
contained in the log files.
</p></li></ul></div>
<p>
For more information on these topics, see the
<i class="citetitle">Berkeley DB Getting Started with Transaction Processing</i> guide and the
<i class="citetitle">Berkeley DB Getting Started with Replicated Applications</i> guide.
</p>
</span>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="key-data"></a>Key-Data Pairs</h3>
</div>
</div>
<div></div>
</div>
<p>
DB stores and retrieves data using
<span class="emphasis"><em>key-data pairs</em></span>. The
<span class="emphasis"><em>data</em></span> portion of this is the data
that you have decided to store in DB for future
retrieval. The <span class="emphasis"><em>key</em></span> is the
information that you want to use to look up your
stored data once it has been placed inside a DB
database.
</p>
<p>
For example, if you were building a database that
contained employee information, then the
<span class="emphasis"><em>data</em></span> portion is all of the
information that you want to store about the employees:
name, address, phone numbers, physical location, their
manager, and so forth.
</p>
<p>
The <span class="emphasis"><em>key</em></span>, however, is the way that
you look up any given employee. You can have more than
one key if you wish, but every record in your database must have a
primary key. If you are using the DPL, then this key must be unique; that is,
it must not be used multiple times in the database. However, if you are using
the base API, then this requirement is relaxed. See
<a href="javadplconcepts.html#duplicatesintro">Duplicate Data</a> for more
information.
</p>
<p>
For example, in the case of an employee database, you would probably use
something like the employee identification number as the primary key as this
uniquely identifies a given employee.
</p>
<p>
You can optionally also have secondary keys that represent indexes
into your database. These keys do not have to be unique
to a given record; in fact, they often are not. For
example, you might set up the employee's manager's name
as a secondary key so that it is easy to locate all
the employee's that work for a given manager.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="storing-intro"></a>Storing Data</h3>
</div>
</div>
<div></div>
</div>
<p>
How you manage your stored information differs
significantly, depending on which API you are using.
Both APIs ultimately are doing the same thing, but the
DPL hides a lot of the details from you.
</p>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="dplstore"></a>Storing Data in the DPL</h4>
</div>
</div>
<div></div>
</div>
<p>
The DPL is used to store Java objects in an
underlying series of databases. These databases are
accessed using an <tt class="classname">EntityStore</tt>
class object.
</p>
<p>
To use the DPL, you must decorate the classes you
want to store with Java annotations that identify them
as either an <span class="emphasis"><em>entity class</em></span> or a
<span class="emphasis"><em>persistent class</em></span>.
</p>
<p>
Entity classes are classes that have a primary key, and
optionally one or more secondary keys. That is, these
are the classes that you will save and retrieve directly
using the DPL. You identify an entity class using the
<tt class="literal">@Entity</tt> java annotation.
</p>
<p>
Persistent classes are classes used by entity classes.
They do not have primary or secondary indices used for
object retrieval. Rather, they are stored or retrieved
when an entity class makes direct use of them. You
identify an persistent class using the
<tt class="literal">@Persistent</tt> java annotation.
</p>
<p>
The primary key for an object is obtained from one of the class' data members.
You identify which data member to use as the primary key using the
<tt class="literal">@PrimaryKey</tt> java annotation.
</p>
<p>
Note that all non-transient instance fields of a
persistent class, as well as its superclasses and
subclasses, are persistent. Static and transient fields
are not persistent. The persistent fields of a class
may be private, package-private (default access),
protected or public.
</p>
<p>
Also, simple Java types, such as
<tt class="classname">java.lang.String</tt> and
<tt class="classname">java.util.Date</tt>, are automatically handled as a
persistent class when you use them in an entity class;
you do not have to do anything special to cause these
simple Java objects to be stored in the
<tt class="classname">EntityStore</tt>.
</p>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="lowlevelstore"></a>Storing Data using the Base API</h4>
</div>
</div>
<div></div>
</div>
<p>
When you are not using the DPL, both record keys and record data must be byte
arrays and are passed to and returned from DB using
<tt class="classname">DatabaseEntry</tt> instances.
<tt class="classname">DatabaseEntry</tt> only supports storage of Java byte arrays.
Complex objects must be marshaled using either Java serialization, or more
efficiently with the bind APIs provided with DB </p>
<p> Database
records and <tt class="literal">byte</tt> array conversion are described in <a href="DBEntry.html">Database Records</a>.
</p>
<p>
You store records in a <tt class="classname">Database</tt> by calling one of the
put methods on a <tt class="classname">Database</tt> handle. DB
automatically determines the record's proper placement in the database's
internal B-Tree using whatever key and data comparison functions that are
available to it.
</p>
<p>
You can also retrieve, or get, records using the
<tt class="classname">Database</tt> handle. Gets are performed by providing the
key (and sometimes also the data) of the record that you want to retrieve.
</p>
<p>
You can also use cursors for database puts and gets. Cursors are essentially
a mechanism by which you can iterate over the records in the database. Like
databases and database environments, cursors must be opened and closed.
Cursors are managed using the <tt class="classname">Cursor</tt> class.
</p>
<p>
Databases are described in <a href="DB.html">Databases</a>. Cursors
are described in <a href="Cursors.html">Using Cursors</a>.
</p>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="duplicatesintro"></a>Duplicate Data</h3>
</div>
</div>
<div></div>
</div>
<p>
If you are using the base API, then at creation time databases can be configured to
allow duplicate data. Remember that DB database records consist of a key/data
pair. <span class="emphasis"><em>Duplicate data</em></span>, then, occurs when two or more records have
identical keys, but different data. By default, a <tt class="classname">Database</tt> does
not allow duplicate data.
</p>
<p>
If your <tt class="classname">Database </tt> contains duplicate data, then a simple
database get based only on a key returns just the first record that uses that key. To
access all duplicate records for that key, you must use a cursor.
</p>
<p>
If you are using the DPL, then you can duplicate date using
secondary keys, but not by using the primary key. For more information, see
<a href="getmultiple.html">Retrieving Multiple Objects</a>.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="replacedeleteIntro"></a>Replacing and Deleting Entries</h3>
</div>
</div>
<div></div>
</div>
<p>
If you are using the DPL, then replacing a stored entity object simply consists of
retrieving it, updating it, then storing it again. To delete the object, use the
<tt class="methodname">delete()</tt> method that is available on either its primary or
secondary keys. If you use the <tt class="methodname">delete()</tt> method available on
the secondary key, then all objects referenced by that key are also deleted.
See <a href="dpl_delete.html">Deleting Entity Objects</a>
for more information.
</p>
<p>
If you are using the base API, then how you replace database records depends on whether
duplicate data is allowed in the database.
</p>
<p>
If duplicate data is not allowed in the database, then simply calling
<tt class="methodname">Database.put()</tt> with the appropriate key will cause any
existing record to be updated with the new data. Similarly, you can delete a record by
providing the appropriate key to the <tt class="methodname">Database.delete()</tt>
method.
</p>
<p>
If duplicate data is allowed in the database, then you must position a cursor to the
record that you want to update, and then perform the put operation using the cursor.
</p>
<p>
To delete records using the base API, you can use either <tt class="methodname">Database.delete()</tt> or
<tt class="methodname">Cursor.delete()</tt>. If duplicate data is not allowed in your
database, then these two method behave identically. However, if duplicates are allowed
in the database, then <tt class="methodname">Database.delete()</tt> deletes every record
that uses the provided key, while <tt class="methodname">Cursor.delete()</tt> deletes just
the record at which the cursor is currently positioned.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="secondary"></a>Secondary Keys</h3>
</div>
</div>
<div></div>
</div>
<p>
Secondary keys provide an alternative way to locate information stored in
DB, beyond that which is provided by the primary key. Frequently secondary
keys refer to more than one record in the database. In this way, you can find
all the cars that are green (if you are maintaining an automotive database) or
all the people with brown eyes (if you are maintaining a database about people).
In other words, secondary keys represent a index into your data.
</p>
<p>
How you create and maintain secondary keys differs significantly, depending on
whether you are using the DPL or the base API.
</p>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="secondarydpl"></a>Using Secondaries with the DPL</h4>
</div>
</div>
<div></div>
</div>
<p>
Under the DPL, you declare a particular field to be a secondary key by
using the <tt class="literal">@SecondaryKey</tt> annotation. When you do this,
you must declare what kind of an index you are creating. For example,
you can declare a secondary key to be part of a
<tt class="literal">ONE_TO_ONE</tt> index, in which case the key is unique to
the object. Or you could declare the key to be
<tt class="literal">MANY_TO_ONE</tt>, in which case the key can be used for
multiple objects in the data store.
</p>
<p>
Once you have identified secondary keys for a class, you can access
those keys by using the <tt class="methodname">EntityStore.getSecondaryIndex()</tt>
method.
</p>
<p>
For more information, see <a href="dplindexcreate.html#dplsecondaryidxdecl">Declaring Secondary Indexes</a>.
</p>
</div>
<div class="sect3" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a id="secondarybaseapi"></a>Using Secondaries with the Base API.</h4>
</div>
</div>
<div></div>
</div>
<p>
When you are using the base API, you create and maintain secondary keys using a
special type of a database, called a <span class="emphasis"><em>secondary database</em></span>.
When you are using secondary databases, the database that holds the data you are
indexing is called the <span class="emphasis"><em>primary database</em></span>.
</p>
<p>
You create a secondary database by opening it and associating it with an
existing primary database. You must also provide a class that generates the
secondary's keys (that is, the index) from primary records. Whenever a
record in the primary database is added or changed, DB uses this class
to determine what the secondary key should be.
</p>
<p>
When a primary record is created, modified, or deleted, DB automatically
updates the secondary database(s) for you as is appropriate for the
operation performed on the primary.
</p>
<p>
You manage secondary databases using the
<tt class="classname">SecondaryDatabase</tt> class. You identify how to create keys
for your secondary databases by supplying an instance of a class that implements
the <tt class="classname">SecondaryKeyCreator</tt> interface.
</p>
<p>
Secondary databases are described in <a href="indexes.html">Secondary Databases</a>.
</p>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="whichapi"></a>Which API Should You Use?</h3>
</div>
</div>
<div></div>
</div>
<p>
Of the two APIs that DB makes available to you, we
recommend that you use the DPL if all
you want to do is make classes with a relatively static schema to
be persistent. However, the DPL requires Java 1.5, so
if you want to use Java 1.4 then you cannot use the DPL.
</p>
<p>
Further, if you are porting an application between the
C or C++ versions of DB and the Java version of
this API, then you should not use the DPL as the
base API is a much closer match to the other languages
available for use with DB.
</p>
<p>
Additionally, if your application uses a highly dynamic
schema, then the DPL is probably a poor choice for
your application, although the use of Java annotations
can make the DPL work a little better for you in this
situation.
</p>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="introduction.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="accessmethods.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 1. Introduction to Berkeley DB  </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Access Methods</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,493 @@
<?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>Secondary Database Example</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="joins.html" title="Database Joins" />
<link rel="next" href="dbconfig.html" title="Chapter 11. Database Configuration" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Secondary Database Example</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="joins.html">Prev</a> </td>
<th width="60%" align="center">Chapter 10. Secondary Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="dbconfig.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="javaindexusage"></a>Secondary Database Example</h2>
</div>
</div>
<div></div>
</div>
<p>In previous chapters in this book, we built applications that load
and display several DB databases. In this example, we will extend those
examples to use secondary databases. Specifically:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>In <a href="dbtJavaUsage.html#dbsStoredClass">Stored Class Catalog Management with MyDbs</a> we built a
class that we can use to open several <tt class="classname">Database</tt> objects.
In <a href="javaindexusage.html#secondaryMyDbs">Opening Secondary Databases with MyDbs</a> we will extend
that class to also open and manage a <tt class="classname">SecondaryDatabase</tt>.
</p>
</li>
<li>
<p>In <a href="cursorJavaUsage.html">Cursor Example</a> we
built an application to display our inventory database (and related
vendor information). In <a href="javaindexusage.html#exampleReadJavaSecondaries">Using Secondary Databases with ExampleDatabaseRead</a> we will extend that application to
show inventory records based on the index we cause to be loaded using
<tt class="classname">ExampleDatabaseLoad</tt>.
</p>
</li>
</ul>
</div>
<p>
Before we can use a secondary database, we must implement a class to extract secondary keys for us.
We use <tt class="classname">ItemNameKeyCreator</tt> for this purpose.
</p>
<div class="example">
<a id="ItemNameKeyCreator-Java"></a>
<p class="title">
<b>Example 10.1 ItemNameKeyCreator.java</b>
</p>
<p>
This class assumes the primary database
uses <tt class="classname">Inventory</tt> objects for the record data. The
<tt class="classname">Inventory</tt> class is described in <a href="dbtJavaUsage.html#inventoryjava">Inventory.java</a>.</p>
<p>In our key creator class, we make use of a custom tuple binding
called <tt class="classname">InventoryBinding</tt>. This class is described in <a href="dbtJavaUsage.html#InventoryJavaBinding">InventoryBinding.java</a>.</p>
<p>You can find <tt class="filename">InventoryBinding.java</tt> in: </p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
<a id="java_index11"></a>
<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.SecondaryKeyCreator;
import com.sleepycat.bind.tuple.TupleBinding;
import java.io.IOException;
public class ItemNameKeyCreator implements SecondaryKeyCreator {
private TupleBinding theBinding;
// Use the constructor to set the tuple binding
ItemNameKeyCreator(TupleBinding binding) {
theBinding = binding;
}
// Abstract method that we must implement
public boolean createSecondaryKey(SecondaryDatabase secDb,
DatabaseEntry keyEntry, // From the primary
DatabaseEntry dataEntry, // From the primary
DatabaseEntry resultEntry) // set the key data on this.
throws DatabaseException {
try {
// Convert dataEntry to an Inventory object
Inventory inventoryItem =
(Inventory) theBinding.entryToObject(dataEntry);
// Get the item name and use that as the key
String theItem = inventoryItem.getItemName();
resultEntry.setData(theItem.getBytes("UTF-8"));
} catch (IOException willNeverOccur) {}
return true;
}
} </pre>
</div>
<p>
Now that we have a key creator, we can use it to generate keys for a
secondary database. We will now extend <tt class="classname">MyDbs</tt>
to manage a secondary database, and to use
<tt class="classname">ItemNameKeyCreator</tt> to generate keys for that
secondary database.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="secondaryMyDbs"></a>Opening Secondary Databases with MyDbs</h3>
</div>
</div>
<div></div>
</div>
<p>In <a href="dbtJavaUsage.html#dbsStoredClass">Stored Class Catalog Management with MyDbs</a> we built
<tt class="classname">MyDbs</tt> as an example of a class that
encapsulates
<tt class="classname">Database</tt> opens and closes. We will now extend
that class to manage a <tt class="classname">SecondaryDatabase</tt>.</p>
<div class="example">
<a id="mydbsSecondary"></a>
<p class="title">
<b>Example 10.2 SecondaryDatabase Management with MyDbs</b>
</p>
<p>
We start by importing two additional classes needed to support secondary databases.
We also add a global variable to use as a handle for our secondary database.
</p>
<a id="java_index12"></a>
<pre class="programlisting">// File MyDbs.java
package db.GettingStarted;
import java.io.FileNotFoundException;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
<b class="userinput"><tt>import com.sleepycat.db.SecondaryConfig;
import com.sleepycat.db.SecondaryDatabase;</tt></b>
public class MyDbs {
// The databases that our application uses
private Database vendorDb = null;
private Database inventoryDb = null;
private Database classCatalogDb = null;
<b class="userinput"><tt>private SecondaryDatabase itemNameIndexDb = null;</tt></b>
private String vendordb = "VendorDB.db";
private String inventorydb = "InventoryDB.db";
private String classcatalogdb = "ClassCatalogDB.db";
<b class="userinput"><tt>private String itemnameindexdb = "ItemNameIndexDB.db";</tt></b>
// Needed for object serialization
private StoredClassCatalog classCatalog;
// Our constructor does nothing
public MyDbs() {} </pre>
<p>
Next we update the <tt class="methodname">MyDbs.setup()</tt> method to open the
secondary database. As a part of this, we have to pass an
<tt class="classname">ItemNameKeyCreator</tt> object on the call to open the secondary
database. Also, in order to instantiate <tt class="classname">ItemNameKeyCreator</tt>, we need an
<tt class="classname">InventoryBinding</tt> object (we described this class in
<a href="dbtJavaUsage.html#InventoryJavaBinding">InventoryBinding.java</a>).
We do all this work together inside of <tt class="methodname">MyDbs.setup()</tt>.
</p>
<a id="java_index13"></a>
<pre class="programlisting"> public void setup(String databasesHome)
throws DatabaseException {
DatabaseConfig myDbConfig = new DatabaseConfig();
<b class="userinput"><tt>SecondaryConfig mySecConfig = new SecondaryConfig();</tt></b>
myDbConfig.setErrorStream(System.err);
<b class="userinput"><tt>mySecConfig.setErrorStream(System.err);</tt></b>
myDbConfig.setErrorPrefix("MyDbs");
<b class="userinput"><tt>mySecConfig.setErrorPrefix("MyDbs");</tt></b>
myDbConfig.setType(DatabaseType.BTREE);
<b class="userinput"><tt>mySecConfig.setType(DatabaseType.BTREE);</tt></b>
myDbConfig.setAllowCreate(true);
<b class="userinput"><tt>mySecConfig.setAllowCreate(true);</tt></b>
// Now open, or create and open, our databases
// Open the vendors and inventory databases
try {
vendordb = databasesHome + "/" + vendordb;
vendorDb = new Database(vendordb,
null,
myDbConfig);
inventorydb = databasesHome + "/" + inventorydb;
inventoryDb = new Database(inventorydb,
null,
myDbConfig);
// Open the class catalog db. This is used to
// optimize class serialization.
classcatalogdb = databasesHome + "/" + classcatalogdb;
classCatalogDb = new Database(classcatalogdb,
null,
myDbConfig);
} catch(FileNotFoundException fnfe) {
System.err.println("MyDbs: " + fnfe.toString());
System.exit(-1);
}
// Create our class catalog
classCatalog = new StoredClassCatalog(classCatalogDb);
// Need a tuple binding for the Inventory class.
// We use the InventoryBinding class
// that we implemented for this purpose.
TupleBinding inventoryBinding = new InventoryBinding();
<b class="userinput"><tt>// Open the secondary database. We use this to create a
// secondary index for the inventory database
// We want to maintain an index for the inventory entries based
// on the item name. So, instantiate the appropriate key creator
// and open a secondary database.
ItemNameKeyCreator keyCreator =
new ItemNameKeyCreator(new InventoryBinding());
// Set up additional secondary properties
// Need to allow duplicates for our secondary database
mySecConfig.setSortedDuplicates(true);
mySecConfig.setAllowPopulate(true); // Allow autopopulate
mySecConfig.setKeyCreator(keyCreator);
// Now open it
try {
itemnameindexdb = databasesHome + "/" + itemnameindexdb;
itemNameIndexDb = new SecondaryDatabase(itemnameindexdb,
null,
inventoryDb,
mySecConfig);
} catch(FileNotFoundException fnfe) {
System.err.println("MyDbs: " + fnfe.toString());
System.exit(-1);
}</tt></b>
}
</pre>
<p>
Next we need an additional getter method for returning the secondary database.
</p>
<a id="java_index14"></a>
<pre class="programlisting"> public SecondaryDatabase getNameIndexDB() {
return itemNameIndexDb;
} </pre>
<p>Finally, we need to update the <tt class="methodname">MyDbs.close()</tt>
method to close the new secondary database. We want to make sure that
the secondary is closed before the primaries. While
this is not necessary for this example because our
closes are single-threaded, it is still a good habit to adopt.</p>
<a id="java_index15"></a>
<pre class="programlisting"> public void close() {
try {
<b class="userinput"><tt>if (itemNameIndexDb != null) {
itemNameIndexDb.close();
}</tt></b>
if (vendorDb != null) {
vendorDb.close();
}
if (inventoryDb != null) {
inventoryDb.close();
}
if (classCatalogDb != null) {
classCatalogDb.close();
}
} catch(DatabaseException dbe) {
System.err.println("Error closing MyDbs: " +
dbe.toString());
System.exit(-1);
}
}
} </pre>
<p>That completes our update to <tt class="classname">MyDbs</tt>. You
can find the complete class implementation in:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="exampleReadJavaSecondaries"></a>Using Secondary Databases with ExampleDatabaseRead</h3>
</div>
</div>
<div></div>
</div>
<p>Because we performed all our secondary database configuration management in
<tt class="classname">MyDbs</tt>, we do not need to modify <tt class="classname">ExampleDatabaseLoad</tt> at all in
order to create our secondary indices. When <tt class="classname">ExampleDatabaseLoad</tt> calls
<tt class="methodname">MyDbs.setup()</tt>, all of the necessary work is performed for us.
</p>
<p>
However, we still need to take advantage of the new secondary indices. We do this by updating
<tt class="classname">ExampleDatabaseRead</tt> to allow us to query for an inventory record based on its name.
Remember that the primary key for an inventory record is the item's SKU. The item's name is contained in the
<tt class="classname">Inventory</tt> object that is stored as each record's data in the inventory database. But
our new secondary index now allows us to easily query based on the item's name.
</p>
<p>
For this update, we modify
<tt class="classname">ExampleDatabaseRead</tt> to accept a new command line switch,
<tt class="literal">-s</tt>, whose argument is the name of an inventory item.
If the switch is present on the command line call to
<tt class="classname">ExampleDatabaseRead</tt>, then the application will
use the secondary database to look up and display all the inventory
records with that item name. Note that we use a <tt class="classname">SecondaryCursor</tt>
to seek to the item name key and then display all matching records.
</p>
<p>Remember that you can find <tt class="filename">ExampleDatabaseRead.java</tt> in: </p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
<div class="example">
<a id="secondaryWithEDR"></a>
<p class="title">
<b>Example 10.3 SecondaryDatabase usage with ExampleDatabaseRead</b>
</p>
<p>
First we need to import an additional class in order to use the secondary cursor:
</p>
<a id="java_index16"></a>
<pre class="programlisting">package db.GettingStarted;
import java.io.IOException;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.db.Cursor;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
<b class="userinput"><tt>import com.sleepycat.db.SecondaryCursor;</tt></b> </pre>
<p>Next we add a single global variable:</p>
<a id="java_index17"></a>
<pre class="programlisting"> public class ExampleDatabaseRead {
private static String myDbsPath = "./";
// Encapsulates the database environment and databases.
private static MyDbs myDbs = new MyDbs();
private static TupleBinding inventoryBinding;
private static EntryBinding vendorBinding;
<b class="userinput"><tt>// The item to locate if the -s switch is used
private static String locateItem;</tt></b> </pre>
<p>Next we update <tt class="methodname">ExampleDatabaseRead.run()</tt> to
check to see if the <tt class="literal">locateItem</tt> global variable has a
value. If it does, then we show just those records related to the item
name passed on the <tt class="literal">-s</tt> switch.</p>
<a id="java_index18"></a>
<pre class="programlisting"> private void run(String args[])
throws DatabaseException {
// Parse the arguments list
parseArgs(args);
myDbs.setup(myDbsPath);
// Setup our bindings.
inventoryBinding = new InventoryBinding();
vendorBinding =
new SerialBinding(myDbs.getClassCatalog(),
Vendor.class);
<b class="userinput"><tt>if (locateItem != null) {
showItem();
} else {</tt></b>
showAllInventory();
<b class="userinput"><tt>}</tt></b>
} </pre>
<p>
Finally, we need to implement <tt class="methodname">ExampleDatabaseRead.showItem()</tt>.
This is a fairly simple method that opens a secondary cursor,
and then displays every primary record that is related to the secondary
key identified by the <tt class="literal">locateItem</tt> global variable.
</p>
<a id="java_index19"></a>
<pre class="programlisting"> private void showItem() throws DatabaseException {
SecondaryCursor secCursor = null;
try {
// searchKey is the key that we want to find in the
// secondary db.
DatabaseEntry searchKey =
new DatabaseEntry(locateItem.getBytes("UTF-8"));
// foundKey and foundData are populated from the primary
// entry that is associated with the secondary db key.
DatabaseEntry foundKey = new DatabaseEntry();
DatabaseEntry foundData = new DatabaseEntry();
// open a secondary cursor
secCursor =
myDbs.getNameIndexDB().openSecondaryCursor(null, null);
// Search for the secondary database entry.
OperationStatus retVal =
secCursor.getSearchKey(searchKey, foundKey,
foundData, LockMode.DEFAULT);
// Display the entry, if one is found. Repeat until no more
// secondary duplicate entries are found
while(retVal == OperationStatus.SUCCESS) {
Inventory theInventory =
(Inventory)inventoryBinding.entryToObject(foundData);
displayInventoryRecord(foundKey, theInventory);
retVal = secCursor.getNextDup(searchKey, foundKey,
foundData, LockMode.DEFAULT);
}
} catch (Exception e) {
System.err.println("Error on inventory secondary cursor:");
System.err.println(e.toString());
e.printStackTrace();
} finally {
if (secCursor != null) {
secCursor.close();
}
}
}</pre>
<p>The only other thing left to do is to update
<tt class="methodname">ExampleDatabaseRead.parseArgs()</tt> to support the <tt class="literal">-s</tt> command
line switch. To see how this is done, see
<tt class="filename">ExampleDatabaseRead.java</tt> in:
</p>
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/db/GettingStarted</pre>
<p>
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
placed your DB distribution.
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="joins.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="dbconfig.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Database Joins </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 11. Database Configuration</td>
</tr>
</table>
</div>
</body>
</html>

367
docs/gsg/JAVA/joins.html Normal file
View File

@@ -0,0 +1,367 @@
<?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>Database Joins</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="secondaryCursor.html" title="&#10; Using Secondary Cursors&#10; &#10; " />
<link rel="next" href="javaindexusage.html" title="Secondary Database Example" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Database Joins</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="secondaryCursor.html">Prev</a> </td>
<th width="60%" align="center">Chapter 10. Secondary Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="javaindexusage.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="joins"></a>Database Joins</h2>
</div>
</div>
<div></div>
</div>
<p>
If you have two or more secondary databases associated with a primary
database, then you can retrieve primary records based on the intersection of
multiple secondary entries. You do this using a
<span><tt class="classname">JoinCursor</tt>.</span>
</p>
<p>
Throughout this document we have presented a
<span>class</span>
that stores
<span>inventory</span>
information on grocery
That
<span>class</span>
is fairly simple with a limited
number of data members, few of which would be interesting from a query
perspective. But suppose, instead, that we were storing
information on something with many more characteristics that can be queried, such
as an automobile. In that case, you may be storing information such as
color, number of doors, fuel mileage, automobile type, number of
passengers, make, model, and year, to name just a few.
</p>
<p>
In this case, you would still likely be using some unique value to key your
primary entries (in the United States, the automobile's VIN would be
ideal for this purpose). You would then create a
<span>class</span>
that identifies
all the characteristics of the automobiles in your inventory.
<span>
You would
also have to create some mechanism by which you would move instances of
this class in and out of Java <tt class="literal">byte</tt> arrays. We
described the concepts and mechanisms by which you can perform these
activities in <a href="DBEntry.html">Database Records</a>.
</span>
</p>
<p>
To query this data, you might then create multiple secondary databases,
one for each of the characteristics that you want to query. For
example, you might create a secondary for color, another for number of
doors, another for number of passengers, and so forth. Of course, you
will need a unique
<span>key creator</span>
for each such secondary database. You do
all of this using the concepts and techniques described throughout this
chapter.
</p>
<p>
Once you have created this primary database and all interesting
secondaries, what you have is the ability to retrieve automobile records
based on a single characteristic. You can, for example, find all the
automobiles that are red. Or you can find all the automobiles that have
four doors. Or all the automobiles that are minivans.
</p>
<p>
The next most natural step, then, is to form compound queries, or joins.
For example, you might want to find all the automobiles that are red,
and that were built by Toyota, and that are minivans. You can do this
using a
<span><tt class="classname">JoinCursor</tt> class instance.</span>
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="joinUsage"></a>Using Join Cursors</h3>
</div>
</div>
<div></div>
</div>
<p>
To use a join cursor:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Open two or more
<span>secondary cursors. These </span>
cursors
<span>for</span>
secondary databases that are associated with
the same primary database.
</p>
</li>
<li>
<p>
Position each such cursor to the secondary key
value in which you are interested. For example, to build on
the previous description, the cursor for the color
database is positioned to the <tt class="literal">red</tt> records
while the cursor for the model database is positioned to the
<tt class="literal">minivan</tt> records, and the cursor for the
make database is positioned to <tt class="literal">Toyota</tt>.
</p>
</li>
<li>
<p>
Create an array of <span>secondary</span> cursors, and
place in it each of the cursors that are participating in your join query.
</p>
</li>
<li>
<p>
Obtain a join cursor. You do this using the
<tt class="methodname">Database.join()</tt>
method. You must pass this method the array of secondary cursors that you
opened and positioned in the previous steps.
</p>
</li>
<li>
<p>
Iterate over the set of matching records
<span>using <tt class="methodname">JoinCursor.getNext()</tt></span>
until
<span><tt class="classname">OperationStatus</tt> is not <tt class="literal">SUCCESS</tt>.</span>
</p>
</li>
<li>
<p>
Close your <span>join</span> cursor.
</p>
</li>
<li>
<p>
If you are done with them, close all your <span>secondary</span> cursors.
</p>
</li>
</ul>
</div>
<p>
For example:
</p>
<a id="java_index9"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.JoinCursor;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
import com.sleepycat.db.SecondaryCursor;
import com.sleepycat.db.SecondaryDatabase;
...
// Database and secondary database opens omitted for brevity.
// Assume a primary database handle:
// automotiveDB
// Assume 3 secondary database handles:
// automotiveColorDB -- index based on automobile color
// automotiveTypeDB -- index based on automobile type
// automotiveMakeDB -- index based on the manufacturer
Database automotiveDB = null;
SecondaryDatabase automotiveColorDB = null;
SecondaryDatabase automotiveTypeDB = null;
SecondaryDatabase automotiveMakeDB = null;
// Query strings:
String theColor = "red";
String theType = "minivan";
String theMake = "Toyota";
// Secondary cursors used for the query:
SecondaryCursor colorSecCursor = null;
SecondaryCursor typeSecCursor = null;
SecondaryCursor makeSecCursor = null;
// The join cursor
JoinCursor joinCursor = null;
// These are needed for our queries
DatabaseEntry foundKey = new DatabaseEntry();
DatabaseEntry foundData = new DatabaseEntry();
// All cursor operations are enclosed in a try block to ensure that they
// get closed in the event of an exception.
try {
// Database entries used for the query:
DatabaseEntry color = new DatabaseEntry(theColor.getBytes("UTF-8"));
DatabaseEntry type = new DatabaseEntry(theType.getBytes("UTF-8"));
DatabaseEntry make = new DatabaseEntry(theMake.getBytes("UTF-8"));
colorSecCursor = automotiveColorDB.openSecondaryCursor(null, null);
typeSecCursor = automotiveTypeDB.openSecondaryCursor(null, null);
makeSecCursor = automotiveMakeDB.openSecondaryCursor(null, null);
// Position all our secondary cursors to our query values.
OperationStatus colorRet =
colorSecCursor.getSearchKey(color, foundData, LockMode.DEFAULT);
OperationStatus typeRet =
typeSecCursor.getSearchKey(type, foundData, LockMode.DEFAULT);
OperationStatus makeRet =
makeSecCursor.getSearchKey(make, foundData, LockMode.DEFAULT);
// If all our searches returned successfully, we can proceed
if (colorRet == OperationStatus.SUCCESS &amp;&amp;
typeRet == OperationStatus.SUCCESS &amp;&amp;
makeRet == OperationStatus.SUCCESS) {
// Get a secondary cursor array and populate it with our
// positioned cursors
SecondaryCursor[] cursorArray = {colorSecCursor,
typeSecCursor,
makeSecCursor};
// Create the join cursor
joinCursor = automotiveDB.join(cursorArray, null);
// Now iterate over the results, handling each in turn
while (joinCursor.getNext(foundKey, foundData, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
// Do something with the key and data retrieved in
// foundKey and foundData
}
}
} catch (DatabaseException dbe) {
// Error reporting goes here
} catch (Exception e) {
// Error reporting goes here
} finally {
try {
// Make sure to close out all our cursors
if (colorSecCursor != null) {
colorSecCursor.close();
}
if (typeSecCursor != null) {
typeSecCursor.close();
}
if (makeSecCursor != null) {
makeSecCursor.close();
}
if (joinCursor != null) {
joinCursor.close();
}
} catch (DatabaseException dbe) {
// Error reporting goes here
}
} </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="joinconfig"></a>JoinCursor Properties</h3>
</div>
</div>
<div></div>
</div>
<p>
You can set <tt class="classname">JoinCursor</tt> properties using the
<tt class="classname">JoinConfig</tt> class. Currently there is just one property that you can
set:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">JoinConfig.setNoSort()</tt>
</p>
<p>
Specifies whether automatic sorting of input cursors is disabled. The cursors are sorted from the
one that refers to the least number of data items to the one that refers to the most.
</p>
<p>
If the data is structured so that cursors with many data items also share many common elements,
higher performance will result from listing those cursors before cursors with fewer data
items. Turning off sorting permits applications to specify cursors in the proper order given this
scenario.
</p>
<p>
The default value is <tt class="literal">false</tt> (automatic cursor sorting is performed).
</p>
<p>
For example:
</p>
<a id="je_index10"></a>
<pre class="programlisting">// All database and environments omitted
JoinConfig config = new JoinConfig();
config.setNoSort(true);
JoinCursor joinCursor = myDb.join(cursorArray, config); </pre>
</li>
</ul>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="secondaryCursor.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="javaindexusage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">
Using Secondary Cursors
 </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Secondary Database Example</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,323 @@
<?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.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="next" href="secondaryProps.html" title="Secondary Database Properties" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Implementing Key
Creators
</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>
</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 <tt class="methodname">SecondaryConfig.setKeyCreator()</tt>
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
<tt class="classname">SecondaryKeyCreator</tt> interface. This interface
requires you to implement the <tt class="methodname">SecondaryKeyCreator.createSecondaryKey()</tt>
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
<tt class="classname">DatabaseEntry</tt> and/or the key's
<tt class="classname">DatabaseEntry</tt> 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 <tt class="classname">EntryBinding</tt> or
<tt class="classname">TupleBinding</tt> that you need to perform the
conversion, and then provide this to your key creator's constructor.
The Bind APIs are introduced in <a href="bindAPI.html">Using the BIND APIs</a>.
</p>
<p>
<tt class="methodname">SecondaryKeyCreator.createSecondaryKey()</tt> returns a
boolean. A return value of <tt class="literal">false</tt> 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,
<tt class="classname">PersonDataBinding</tt>, that you use to convert
<tt class="classname">PersonData</tt> objects to and from
<tt class="classname">DatabaseEntry</tt> objects. (Custom tuple bindings are
described in <a href="bindAPI.html#customTuple">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.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></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
<tt class="classname">SecondaryMultiKeyCreator</tt>
instead of
<tt class="classname">SecondaryKeyCreator</tt>. The key
difference between the two is that
<tt class="classname">SecondaryKeyCreator</tt>
uses a single <tt class="classname">DatabaseEntry</tt>
object as the result, while
<tt class="classname">SecondaryMultiKeyCreator</tt>
returns a set of <tt class="classname">DatabaseEntry</tt>
objects (using <tt class="classname">java.util.Set</tt>).
Also, you assign the
<tt class="classname">SecondaryMultiKeyCreator</tt>
implementation using
<tt class="methodname">SecondaryConfig.setMultiKeyCreator()</tt>
instead of
<tt class="methodname">SecondaryConfig.setKeyCreator()</tt>.
</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>

View File

@@ -0,0 +1,160 @@
<?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>MyDbEnv</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl_example.html" title="Chapter 6. A DPL Example" />
<link rel="previous" href="inventoryclass.html" title="Inventory.class" />
<link rel="next" href="dataaccessorclass.html" title="DataAccessor.class" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">MyDbEnv</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="inventoryclass.html">Prev</a> </td>
<th width="60%" align="center">Chapter 6. A DPL Example</th>
<td width="20%" align="right"> <a accesskey="n" href="dataaccessorclass.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="mydbenv-persist"></a>MyDbEnv</h2>
</div>
</div>
<div></div>
</div>
<p>
The applications that we are building for our example both
must open and close environments and entity stores. One
of our applications is writing to the entity store, so this
application needs to open the store as read-write. It also
wants to be able to create the store if it does not exist.
</p>
<p>
Our second application only reads from the store. In this
case, the store should be opened as read-only.
</p>
<p>
We perform these activities by creating a single class that
is responsible for opening and closing our store and
environment. This class is shared by both our applications.
To use it, callers need to only provide the path to the
environment home directory, and to indicate whether the
object is meant to be read-only. The class implementation
is as follows:
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import java.io.FileNotFoundException;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;
public class MyDbEnv {
private Environment myEnv;
private EntityStore store;
// Our constructor does nothing
public MyDbEnv() {}
// The setup() method opens the environment and store
// for us.
public void setup(File envHome, boolean readOnly)
throws DatabaseException {
EnvironmentConfig myEnvConfig = new EnvironmentConfig();
StoreConfig storeConfig = new StoreConfig();
myEnvConfig.setReadOnly(readOnly);
storeConfig.setReadOnly(readOnly);
// If the environment is opened for write, then we want to be
// able to create the environment and entity store if
// they do not exist.
myEnvConfig.setAllowCreate(!readOnly);
storeConfig.setAllowCreate(!readOnly);
try {
// Open the environment and entity store
myEnv = new Environment(envHome, myEnvConfig);
store = new EntityStore(myEnv, "EntityStore", storeConfig);
} catch (FileNotFoundException fnfe) {
System.err.println("setup(): " + fnfe.toString());
System.exit(-1);
}
}
// Return a handle to the entity store
public EntityStore getEntityStore() {
return store;
}
// Return a handle to the environment
public Environment getEnv() {
return myEnv;
}
// Close the store and environment.
public void close() {
if (store != null) {
try {
store.close();
} catch(DatabaseException dbe) {
System.err.println("Error closing store: " +
dbe.toString());
System.exit(-1);
}
}
if (myEnv != null) {
try {
// Finally, close the environment.
myEnv.close();
} catch(DatabaseException dbe) {
System.err.println("Error closing MyDbEnv: " +
dbe.toString());
System.exit(-1);
}
}
}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="inventoryclass.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl_example.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dataaccessorclass.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Inventory.class </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> DataAccessor.class</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,242 @@
<?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>Chapter 5. Saving and Retrieving Objects</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl.html" title="Part I. Programming with the Direct Persistence Layer" />
<link rel="previous" href="dplindexcreate.html" title="Creating Indexes" />
<link rel="next" href="simpleda.html" title="SimpleDA.class" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 5. Saving and Retrieving Objects</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dplindexcreate.html">Prev</a> </td>
<th width="60%" align="center">Part I. Programming with the Direct Persistence Layer</th>
<td width="20%" align="right"> <a accesskey="n" href="simpleda.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="persist_access"></a>Chapter 5. Saving and Retrieving Objects</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="persist_access.html#simpleentity">A Simple Entity Class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleda.html">SimpleDA.class</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleput.html">Placing Objects in an Entity Store</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="simpleget.html">Retrieving Objects from an Entity Store</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="getmultiple.html">Retrieving Multiple Objects</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_cursor_initialize">Cursor Initialization</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_dups">Working with Duplicate Keys</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="getmultiple.html#dpl_cursor_range">Key Ranges</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dpl_entityjoin.html">Join Cursors</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_delete.html">Deleting Entity Objects</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="dpl_replace.html">Replacing Entity Objects</a>
</span>
</dt>
</dl>
</div>
<p>
To store an object in an <tt class="classname">EntityStore</tt> you
must annotate the class appropriately and then store it using
<tt class="methodname">PrimaryIndex.put()</tt>.
</p>
<p>
To retrieve and object from an <tt class="classname">EntityStore</tt>
you use the <tt class="methodname">get()</tt> method from either the
<tt class="classname">PrimaryIndex</tt> or
<tt class="classname">SecondaryIndex</tt>, whichever is most
appropriate for your application.
</p>
<p>
In both cases, it simplifies things greatly if you create a data
accessor class to organize your indexes.
</p>
<p>
In the next few sections we:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Create an entity class that is ready to be stored
in an entity store. This class will have both a
primary index (required) declared for it, as well
as a secondary index (which is optional).
</p>
<p>
See the next section for this implementation.
</p>
</li>
<li>
<p>
Create a data accessor class which is used to
organize our data.
</p>
<p>
See <a href="simpleda.html">SimpleDA.class</a>
for this implementation.
</p>
</li>
<li>
<p>
Create a simple class that is used to put objects
to our entity store.
</p>
<p>
See <a href="simpleput.html">Placing Objects in an Entity Store</a>
for this implementation.
</p>
</li>
<li>
<p>
Create another class that retrieves objects from
our entity store.
</p>
<p>
See <a href="simpleget.html">Retrieving Objects from an Entity Store</a>
for this implementation.
</p>
</li>
</ol>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="simpleentity"></a>A Simple Entity Class</h2>
</div>
</div>
<div></div>
</div>
<p>
For clarity's sake, this entity class is a simple a class as we can write.
It contains only two data members, both of which are set
and retrieved by simple setter and getter methods. Beyond
that, by design this class does not do anything or particular
interest.
</p>
<p>
Its implementation is as follows:
</p>
<pre class="programlisting">package persist.gettingStarted;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.PrimaryKey;
import static com.sleepycat.persist.model.Relationship.*;
import com.sleepycat.persist.model.SecondaryKey;
@Entity
public class SimpleEntityClass {
// Primary key is pKey
@PrimaryKey
private String pKey;
// Secondary key is the sKey
@SecondaryKey(relate=MANY_TO_ONE)
private String sKey;
public void setpKey(String data) {
pKey = data;
}
public void setsKey(String data) {
sKey = data;
}
public String getpKey() {
return pKey;
}
public String getsKey() {
return sKey;
}
} </pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dplindexcreate.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="simpleda.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Creating Indexes </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> SimpleDA.class</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,310 @@
<?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>Chapter 3. Direct Persistence Layer First Steps</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl.html" title="Part I. Programming with the Direct Persistence Layer" />
<link rel="previous" href="dpl.html" title="Part I. Programming with the Direct Persistence Layer" />
<link rel="next" href="persistobject.html" title="Persistent Objects" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 3. Direct Persistence Layer First Steps</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="dpl.html">Prev</a> </td>
<th width="60%" align="center">Part I. Programming with the Direct Persistence Layer</th>
<td width="20%" align="right"> <a accesskey="n" href="persistobject.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="persist_first"></a>Chapter 3. Direct Persistence Layer First Steps</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="persist_first.html#entitystore">Entity Stores</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="persist_first.html#persist-open">Opening and Closing Environments and Stores</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="persistobject.html">Persistent Objects</a>
</span>
</dt>
<dt>
<span class="sect1">
<a href="saveret.html">Saving a Retrieving Data</a>
</span>
</dt>
</dl>
</div>
<p>
This chapter guides you through the first few steps required to
use the DPL with your application. These steps include:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Opening your environment as was described in
<span>
<a href="Env.html#EnvOpen">Opening Database Environments</a>.
</span>
</p>
</li>
<li>
<p>
Opening your entity store.
</p>
</li>
<li>
<p>
Identifying the classes that you want to store in
DB as either a <tt class="literal">persistent</tt>
class or an <tt class="literal">entity</tt>.
</p>
</li>
</ol>
</div>
<p>
Once you have done these things, you can write your classes to
the DB databases, read them back from the databases, delete
them from the databases, and so forth. These activities are
described in the chapters that follow in this part of this manual.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="entitystore"></a>Entity Stores</h2>
</div>
</div>
<div></div>
</div>
<p>
Entity stores are the basic unit of storage that you use with the DPL. That is, it
is a unit of encapsulation for the classes that you want to store in DB. Under
the hood it actually interacts with DB databases, but the DPL provides a layer
of abstraction from the underlying DB APIs. The store, therefore, provides a
simplified mechanism by which you read and write your stored classes. By using a
store, you have access to your classes that is more simplified than if you were
interacting with databases directly, but this simplified access comes at the cost of
reduced flexibility.
</p>
<p>
Entity stores have configurations in the same way that environments have
configurations. You can use a <tt class="classname">StoreConfig</tt> object
to identify store properties. Among these are methods that allow you to declare
whether:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
the store can be created if it does not exist at the time
it is opened. Use the
<tt class="methodname">StoreConfig.setAllowCreate()</tt>
method to set this.
</p>
</li>
<li>
<p>
deferred writes are allowed for the store. Use the
<tt class="methodname">StoreConfig.setDeferredWrite()</tt>
method to set this.
</p>
</li>
<li>
<p>
the store is read-only. Use the
<tt class="methodname">StoreConfig.setReadOnly()</tt>
method to set this.
</p>
</li>
<li>
<p>
the store supports transactions. Use the
<tt class="methodname">StoreConfig.setTransactional()</tt>
method to set this.
</p>
<p>
Writing DB transactional applications is described in the
<i class="citetitle">Berkeley DB Java Edition Getting Started with Transaction Processing</i> guide.
</p>
</li>
</ul>
</div>
<p>
<tt class="classname">EntityStore</tt> objects also provide methods for retrieving
information about the store, such as:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
the store's name. Use the
<tt class="methodname">EntityStore.getStoreName()</tt>
method to retrieve this.
</p>
</li>
<li>
<p>
a handle to the environment in which the store is opened. Use the
<tt class="methodname">EntityStore.getEnvironment</tt>
method to retrieve this handle.
</p>
</li>
</ul>
</div>
<p>
You can also use the <tt class="classname">EntityStore</tt> to
retrieve all the primary and secondary indexes related to a given type of entity
object contained in the store. See <a href="persist_index.html">Working with Indices</a> for
more information.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="persist-open"></a>Opening and Closing Environments and Stores</h3>
</div>
</div>
<div></div>
</div>
<p>
As described in
<span>
<a href="Env.html">Database Environments</a>,
</span>
an
<span class="emphasis"><em>environment</em></span> is a unit of
encapsulation for DB databases. It also provides a
handle by which activities common across the databases
can be managed.
</p>
<p>
To use an entity store, you must first open an environment and then provide that
environment handle to the <tt class="classname">EntityStore</tt> constructor.
</p>
<p>
For example, the following code fragment configures both
the environment and the entity store such that they can
be created if they do not exist. Both the environment and
the entity store are then opened.
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import java.io.FileNotFoundException;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;
...
private Environment myEnv;
private EntityStore store;
try {
EnvironmentConfig myEnvConfig = new EnvironmentConfig();
StoreConfig storeConfig = new StoreConfig();
myEnvConfig.setAllowCreate(!readOnly);
storeConfig.setAllowCreate(!readOnly);
try {
// Open the environment and entity store
myEnv = new Environment(envHome, myEnvConfig);
store = new EntityStore(myEnv, "EntityStore", storeConfig);
} catch (FileNotFoundException fnfe) {
System.err.println(fnfe.toString());
System.exit(-1);
}
} catch(DatabaseException dbe) {
System.err.println("Error opening environment and store: " +
dbe.toString());
System.exit(-1);
} </pre>
<p>
As always, before you exit your program you should close both
your store and your environment. Be sure to close your store before you close your
environment.
</p>
<pre class="programlisting">if (store != null) {
try {
store.close();
} catch(DatabaseException dbe) {
System.err.println("Error closing store: " +
dbe.toString());
System.exit(-1);
}
}
if (myEnv != null) {
try {
// Finally, close environment.
myEnv.close();
} catch(DatabaseException dbe) {
System.err.println("Error closing MyDbEnv: " +
dbe.toString());
System.exit(-1);
}
} </pre>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="dpl.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="persistobject.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Part I. Programming with the Direct Persistence Layer </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Persistent Objects</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,232 @@
<?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>Chapter 4. Working with Indices</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="dpl.html" title="Part I. Programming with the Direct Persistence Layer" />
<link rel="previous" href="saveret.html" title="Saving a Retrieving Data" />
<link rel="next" href="dplindexcreate.html" title="Creating Indexes" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 4. Working with Indices</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="saveret.html">Prev</a> </td>
<th width="60%" align="center">Part I. Programming with the Direct Persistence Layer</th>
<td width="20%" align="right"> <a accesskey="n" href="dplindexcreate.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="persist_index"></a>Chapter 4. Working with Indices</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="persist_index.html#dplindexaccess">Accessing Indexes</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="persist_index.html#primaryindexaccess">Accessing Primary Indices</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="persist_index.html#secondaryindexaccess">Accessing Secondary Indices</a>
</span>
</dt>
</dl>
</dd>
<dt>
<span class="sect1">
<a href="dplindexcreate.html">Creating Indexes</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#dplprimaryidxdecl">Declaring a Primary Indexes</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#dplsecondaryidxdecl">Declaring Secondary Indexes</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="dplindexcreate.html#foreignkey">Foreign Key Constraints</a>
</span>
</dt>
</dl>
</dd>
</dl>
</div>
<p>
All entity classes stored in DB using the DPL must have a
primary index, or key, identified for them. All such classes may
also have one or more secondary keys declared for them. This
chapter describes primary and secondary indexes in detail, and
shows how to access the indexes created for a given entity class.
</p>
<p>
One way to organize access to your primary and secondary
indexes is to create a <span class="emphasis"><em>data accessor</em></span>
class. We show an implementation of a data accessor class in
<a href="simpleda.html">SimpleDA.class</a>.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="dplindexaccess"></a>Accessing Indexes</h2>
</div>
</div>
<div></div>
</div>
<p>
In order to retrieve any object from an entity store, you
must access at least the primary index for that object.
Different entity classes stored in an entity store can have
different primary indexes, but all entity classes must have a
primary index declared for it. The primary index is just
the default index used for the class. (That is, it is the
data's <span class="emphasis"><em>key</em></span> for the underlying database.)
</p>
<p>
Entity classes can optionally have secondary indexes
declared for them. In order to access these secondary
indexes, you must first access the primary index.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="primaryindexaccess"></a>Accessing Primary Indices</h3>
</div>
</div>
<div></div>
</div>
<p>
You retrieve a primary index using the
<tt class="methodname">EntityStore.getPrimaryIndex()</tt>
method. To do this, you indicate the index key type
(that is, whether it is a String, Integer, and
so forth) and the class of the entities stored
in the index.
</p>
<p>
For example, the following retrieves the
primary index for an <tt class="classname">Inventory</tt>
class (we provide an implementation of this class in
<a href="inventoryclass.html">Inventory.class</a>).
These index keys are of type <tt class="classname">String</tt>.
</p>
<pre class="programlisting">PrimaryIndex&lt;String,Inventory&gt; inventoryBySku =
store.getPrimaryIndex(String.class, Inventory.class); </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="secondaryindexaccess"></a>Accessing Secondary Indices</h3>
</div>
</div>
<div></div>
</div>
<p>
You retrieve a secondary index using the
<tt class="methodname">EntityStore.getSecondaryIndex()</tt>
method. Because secondary indices actually
refer to a primary index somewhere in your data
store, to access a secondary index you:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Provide the primary index as
returned by
<tt class="methodname">EntityStore.getPrimaryIndex()</tt>.
</p>
</li>
<li>
<p>
Identify the key data type used by
the secondary index
(<tt class="classname">String</tt>,
<tt class="classname">Long</tt>,
and so forth).
</p>
</li>
<li>
<p>
Identify the name of the
secondary key field.
When you declare the
<tt class="classname">SecondaryIndex</tt>
object, you identify the entity class
to which the secondary index
must refer.
</p>
</li>
</ol>
</div>
<p>
For example, the following first retrieves the
primary index, and then uses that to retrieve a secondary
index. The secondary key is held by the
<tt class="literal">itemName</tt> field of the
<tt class="classname">Inventory</tt> class.
</p>
<pre class="programlisting">PrimaryIndex&lt;String,Inventory&gt; inventoryBySku =
store.getPrimaryIndex(String.class, Inventory.class);
SecondaryIndex&lt;String,String,Inventory&gt; inventoryByName =
store.getSecondaryIndex(inventoryBySku, String.class, "itemName"); </pre>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="saveret.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="dpl.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dplindexcreate.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Saving a Retrieving Data </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Creating Indexes</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,148 @@
<?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>Persistent Objects</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_first.html" title="Chapter 3. Direct Persistence Layer First Steps" />
<link rel="previous" href="persist_first.html" title="Chapter 3. Direct Persistence Layer First Steps" />
<link rel="next" href="saveret.html" title="Saving a Retrieving Data" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Persistent Objects</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="persist_first.html">Prev</a> </td>
<th width="60%" align="center">Chapter 3. Direct Persistence Layer First Steps</th>
<td width="20%" align="right"> <a accesskey="n" href="saveret.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="persistobject"></a>Persistent Objects</h2>
</div>
</div>
<div></div>
</div>
<p>
When using the DPL, you store data in the underlying
DB databases by making objects
<span class="emphasis"><em>persistent</em></span>. You do this using Java
annotations that both identify the type of persistent
object you are declaring, as well as the primary and
secondary indices.
</p>
<p>
The following are the annotations you will use with your
DPL persistent classes:
</p>
<div class="informaltable">
<table border="1" width="80%">
<colgroup>
<col />
<col />
</colgroup>
<thead>
<tr>
<th>Annotation</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>@Entity</td>
<td>
Declares an entity class; that is, a class with a primary index
and optionally one or more indices.
</td>
</tr>
<tr>
<td>@Persistent</td>
<td>
Declares a persistent class; that is, a class used by an entity
class. They do not have indices but instead are are stored or
retrieved when an entity class makes direct use of them.
</td>
</tr>
<tr>
<td>@PrimaryKey</td>
<td>
Declares a specific data member in an entity class to be the
primary key for that object. This annotation must be used one
and only one time for every entity class.
</td>
</tr>
<tr>
<td>@SecondaryKey</td>
<td>
Declares a specific data member in an entity class to be a
secondary key for that object. This annotation is optional, and
can be used multiple times for an entity class.
</td>
</tr>
</tbody>
</table>
</div>
<p>
For example, the following is declared to be an entity class:
</p>
<pre class="programlisting">package persist.gettingStarted;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.PrimaryKey;
@Entity
public class ExampleEntity {
private String aPrimaryKey;
private String aSecondaryKey;
// The primary key must be unique in the database.
@PrimaryKey
private String aPrimaryKey;
@SecondaryKey(relate=MANY_TO_ONE)
private String aSecondaryKey;
...
// The remainder of the class' implementation is purposefully
// omitted in the interest of brevity.
...
} </pre>
<p>
We discuss primary and secondary keys in more detail in <a href="persist_index.html">Working with Indices</a>.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="persist_first.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_first.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="saveret.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 3. Direct Persistence Layer First Steps </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Saving a Retrieving Data</td>
</tr>
</table>
</div>
</body>
</html>

228
docs/gsg/JAVA/preface.html Normal file
View File

@@ -0,0 +1,228 @@
<?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>Preface</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="previous" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="next" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Preface</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="index.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="introduction.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="preface" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a id="preface"></a>Preface</h2>
</div>
</div>
<div></div>
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<span class="sect1">
<a href="preface.html#conventions">Conventions Used in this Book</a>
</span>
</dt>
<dd>
<dl>
<dt>
<span class="sect2">
<a href="preface.html#moreinfo">For More Information</a>
</span>
</dt>
</dl>
</dd>
</dl>
</div>
<p>
Welcome to Berkeley DB (DB). This document introduces
<span>DB, version 4.7. </span>
It is intended
to provide a rapid introduction to the DB API set and related concepts. The goal of this document is
to provide you with an efficient mechanism
with which you can evaluate DB against your project's technical requirements. As such, this document is
intended for <span>Java</span>
developers and senior software architects who are
looking for an
<span>
in-process data management solution.
</span>
No prior experience with Berkeley DB is expected or required.
</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="conventions"></a>Conventions Used in this Book</h2>
</div>
</div>
<div></div>
</div>
<p>
The following typographical conventions are used within in this manual:
</p>
<p>
Class names are represented in <tt class="classname">monospaced font</tt>, as are <tt class="methodname">method
names</tt>. For example:
<span>"The <tt class="methodname">Database()</tt>
constructor returns a <tt class="classname">Database</tt> class object."</span>
</p>
<p>
Variable or non-literal text is presented in <span class="emphasis"><em>italics</em></span>. For example: "Go to your
<span class="emphasis"><em>DB_INSTALL</em></span>
directory."
</p>
<p>
Program examples are displayed in a <tt class="classname">monospaced font</tt> on a shaded background.
For example:
</p>
<pre class="programlisting">import com.sleepycat.db.DatabaseConfig;
...
// Allow the database to be created.
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(true);</pre>
<p>
In some situations, programming examples are updated from one chapter to the next. When
this occurs, the new code is presented in <b class="userinput"><tt>monospaced bold</tt></b> font. For example:
</p>
<pre class="programlisting"><b class="userinput"><tt>import com.sleepycat.db.Database;</tt></b>
import com.sleepycat.db.DatabaseConfig;
...
// Allow the database to be created.
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(true);
<b class="userinput"><tt>Database myDb = new Database("mydb.db", null, myDbConfig);</tt></b> </pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
Finally, notes of interest are represented using a note block such
as this.
</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="moreinfo"></a>For More Information</h3>
</div>
</div>
<div></div>
</div>
<p>
Beyond this manual, you may also find the following sources of information useful when building a
DB application:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/gsg_txn/JAVA/index.html" target="_top">
Getting Started with Transaction Processing for Java
</a>
</p>
</li>
<li>
<p>
<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/gsg_db_rep/JAVA/index.html" target="_top">
Berkeley DB Getting Started with Replicated Applications for Java
</a>
</p>
</li>
<li>
<p>
<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/ref/toc.html" target="_top">
Berkeley DB Programmer's Reference Guide
</a>
</p>
</li>
<li>
<p>
<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/java/index.html" target="_top">
Berkeley DB Javadoc
</a>
</p>
</li>
<li>
<p>
<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/collections/tutorial/index.html" target="_top">
Berkeley DB Collections Tutorial
</a>
</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="index.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="index.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="introduction.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Getting Started with Berkeley DB </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 1. Introduction to Berkeley DB </td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,124 @@
<?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>Reading Secondary Databases</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="secondaryProps.html" title="Secondary Database Properties" />
<link rel="next" href="secondaryDelete.html" title="Deleting Secondary Database Records" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Reading Secondary Databases</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="secondaryProps.html">Prev</a> </td>
<th width="60%" align="center">Chapter 10. Secondary Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="secondaryDelete.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="readSecondary"></a>Reading Secondary Databases</h2>
</div>
</div>
<div></div>
</div>
<p>
Like a primary database, you can read records from your secondary
database either by using the
<span>
<tt class="methodname">SecondaryDatabase.get()</tt> method,
</span>
or by using
<span>a <tt class="classname">SecondaryCursor</tt>.</span>
The main difference between reading secondary and primary databases is that when
you read a secondary database record, the secondary record's data is not
returned to you. Instead, the primary key and data corresponding to the
secondary key are returned to you.
</p>
<p>
For example, assuming your secondary database contains keys related
to a person's full name:
</p>
<a id="java_index6"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
import com.sleepycat.db.SecondaryDatabase;
...
SecondaryDatabase mySecondaryDatabase = null;
try {
// Omitting all database opens
...
String searchName = "John Doe";
DatabaseEntry searchKey =
new DatabaseEntry(searchName.getBytes("UTF-8"));
DatabaseEntry primaryKey = new DatabaseEntry();
DatabaseEntry primaryData = new DatabaseEntry();
// Get the primary key and data for the user 'John Doe'.
OperationStatus retVal = mySecondaryDatabase.get(null, searchKey,
primaryKey,
primaryData,
LockMode.DEFAULT);
} catch (Exception e) {
// Exception handling goes here
}</pre>
<p>
Note that, just like
<span><tt class="methodname">Database.get()</tt>, </span>
if your secondary database supports duplicate records then
<tt class="methodname">SecondaryDatabase.get()</tt>
only return the first record found in a matching duplicates set. If you
want to see all the records related to a specific secondary key, then use a
<span>
<tt class="classname">SecondaryCursor</tt> (described in <a href="secondaryCursor.html">
<span>Using Secondary Cursors</span>
</a>).
</span>
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="secondaryProps.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="secondaryDelete.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Secondary Database Properties </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Deleting Secondary Database Records</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,81 @@
<?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>Error Returns</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="introduction.html" title="Chapter 1. Introduction to Berkeley DB " />
<link rel="previous" href="coreExceptions.html" title="Exception Handling" />
<link rel="next" href="gettingit.html" title="Getting and Using DB " />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Error Returns</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="coreExceptions.html">Prev</a> </td>
<th width="60%" align="center">Chapter 1. Introduction to Berkeley DB </th>
<td width="20%" align="right"> <a accesskey="n" href="gettingit.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="returns"></a>Error Returns</h2>
</div>
</div>
<div></div>
</div>
<p>
<span>In addition to exceptions, the</span>
DB interfaces always return a value of 0 on success. If the
operation does not succeed for any reason, the return value will be
non-zero.
</p>
<p>
If a system error occurred (for example, DB ran out of disk
space, or permission to access a file was denied, or an illegal argument
was specified to one of the interfaces), DB returns an
<tt class="literal">errno</tt>
value. All of the possible values of <tt class="literal">errno</tt> are greater than 0.
</p>
<p>
If the operation did not fail due to a system error, but was not
successful either, DB returns a special error value. For
example, if you tried to retrieve data from the database and the
record for which you are searching does not exist, DB would return
<tt class="literal">DB_NOTFOUND</tt>, a special error value that means the requested
key does not appear in the database. All of the possible special error
values are less than 0.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="coreExceptions.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="introduction.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="gettingit.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Exception Handling </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Getting and Using DB </td>
</tr>
</table>
</div>
</body>
</html>

121
docs/gsg/JAVA/saveret.html Normal file
View File

@@ -0,0 +1,121 @@
<?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>Saving a Retrieving Data</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_first.html" title="Chapter 3. Direct Persistence Layer First Steps" />
<link rel="previous" href="persistobject.html" title="Persistent Objects" />
<link rel="next" href="persist_index.html" title="Chapter 4. Working with Indices" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Saving a Retrieving Data</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="persistobject.html">Prev</a> </td>
<th width="60%" align="center">Chapter 3. Direct Persistence Layer First Steps</th>
<td width="20%" align="right"> <a accesskey="n" href="persist_index.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="saveret"></a>Saving a Retrieving Data</h2>
</div>
</div>
<div></div>
</div>
<p>
All data stored using the DPL has one primary index and
zero or more secondary indices associated with it.
(Sometimes these are referred to as the primary and
secondary <span class="emphasis"><em>keys</em></span>.) So to store data under the DPL, you must:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Declare a class to be an entity class.
</p>
</li>
<li>
<p>
Identify the features on the class which
represent indexed material.
</p>
</li>
<li>
<p>
Retrieve the store's primary index for a
given class using the
<tt class="methodname">EntityStore.getPrimaryIndex()</tt>
method.
</p>
</li>
<li>
<p>
Put class objects to the store using the
<tt class="methodname">PrimaryIndex.put()</tt>
method.
</p>
</li>
</ol>
</div>
<p>
In order to retrieve an object from the store, you use
the index that is most convenient for your purpose. This
may be the primary index, or it may be some other
secondary index that you declared on your entity class.
</p>
<p>
You obtain a primary index in the same was as when you
put the object to the store: using
<tt class="methodname">EntityStore.getPrimaryIndex()</tt>.
You can get a secondary index for the store using the
<tt class="methodname">EntityStore.getSecondaryIndex()</tt>
method. Note that
<tt class="methodname">getSecondaryIndex()</tt> requires you
to provide a <tt class="classname">PrimaryIndex</tt> class
instance when you call it, so a class's primary index is
always required when retrieving objects from an entity
store.
</p>
<p>
Usually all of the activity surrounding saving and
retrieving data is organized within a class or classes
specialized to that purpose. We describe the construction
of these data accessor classes in <a href="simpleda.html">SimpleDA.class</a>. But before you perform
any entity store activity, you need to understand
indexes. We therefore describe them in the next chapter.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="persistobject.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_first.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="persist_index.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Persistent Objects </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Chapter 4. Working with Indices</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,157 @@
<?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>
Using Secondary Cursors
</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="secondaryDelete.html" title="Deleting Secondary Database Records" />
<link rel="next" href="joins.html" title="Database Joins" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">
Using Secondary Cursors
</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="secondaryDelete.html">Prev</a> </td>
<th width="60%" align="center">Chapter 10. Secondary Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="joins.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="secondaryCursor"></a>
<span>Using Secondary Cursors</span>
</h2>
</div>
</div>
<div></div>
</div>
<p>
Just like cursors on a primary database, you can use
<span>secondary cursors</span>
to iterate over the records in a secondary database. Like
<span>normal cursors,</span>
you can also use
<span>secondary cursors</span>
to search for specific records in a database, to seek to the first
or last record in the database, to get the next duplicate record,
and so forth. For a complete description on cursors and their capabilities, see
<a href="Cursors.html">Using Cursors</a>.
</p>
<p>
However, when you use
<span>secondary cursors:</span>
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
Any data returned is the data contained on the primary database
record referenced by the secondary record.
</p>
</li>
<li>
<p>
<tt class="methodname">SecondaryCursor.getSearchBoth()</tt> and
related methods do not search based on a key/data pair. Instead, you
search based on a secondary key and a primary key. The data returned
is the primary data that most closely matches the two keys provided
for the search.
</p>
</li>
</ul>
</div>
<p>
For example, suppose you are using the databases, classes, and key
<span>creators</span>
described in <a href="keyCreator.html">Implementing Key
<span>Creators</span>
</a>.
Then the following searches for a person's
name in the secondary database, and deletes all secondary and primary
records that use that name.
</p>
<a id="java_index8"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
import com.sleepycat.db.SecondaryDatabase;
import com.sleepycat.db.SecondaryCursor;
...
try {
SecondaryDatabase mySecondaryDatabase = null;
// Database opens omitted for brevity
...
String secondaryName = "John Doe";
DatabaseEntry secondaryKey =
new DatabaseEntry(secondaryName.getBytes("UTF-8"));
DatabaseEntry foundData = new DatabaseEntry();
SecondaryCursor mySecCursor =
mySecondaryDatabase.openSecondaryCursor(null, null);
OperationStatus retVal = mySecCursor.getSearchKey(secondaryKey,
foundData,
LockMode.DEFAULT);
while (retVal == OperationStatus.SUCCESS) {
mySecCursor.delete();
retVal = mySecCursor.getNextDup(secondaryKey,
foundData,
LockMode.DEFAULT);
}
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="secondaryDelete.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="joins.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Deleting Secondary Database Records </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Database Joins</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,132 @@
<?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>Deleting Secondary Database Records</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="readSecondary.html" title="Reading Secondary Databases" />
<link rel="next" href="secondaryCursor.html" title="&#10; Using Secondary Cursors&#10; &#10; " />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Deleting Secondary Database Records</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="readSecondary.html">Prev</a> </td>
<th width="60%" align="center">Chapter 10. Secondary Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="secondaryCursor.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="secondaryDelete"></a>Deleting Secondary Database Records</h2>
</div>
</div>
<div></div>
</div>
<p>
In general, you
<span>will</span>
not modify a secondary database directly. In
order to modify a secondary database, you should modify the primary
database and simply allow DB to manage the secondary modifications for you.
</p>
<p>
However, as a convenience, you can delete
<tt class="classname">SecondaryDatabase</tt>
records directly. Doing so causes the associated primary key/data pair to be deleted.
This in turn causes DB to delete all
<tt class="classname">SecondaryDatabase</tt>
records that reference the primary record.
</p>
<p>
You can use the
<tt class="methodname">SecondaryDatabase.delete()</tt>
method to delete a secondary database record.
<span>Note that if your
<tt class="classname">SecondaryDatabase</tt>
contains duplicate records, then deleting a record from the set of
duplicates causes all of the duplicates to be deleted as well.
</span>
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
<span><tt class="methodname">SecondaryDatabase.delete()</tt> causes the
previously described delete operations to occur
</span>
only if the primary database is opened for write access.
</p>
</div>
<p>For example:</p>
<a id="java_index7"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.OperationStatus;
import com.sleepycat.db.SecondaryDatabase;
...
try {
SecondaryDatabase mySecondaryDatabase = null;
// Omitting all database opens
...
String searchName = "John Doe";
DatabaseEntry searchKey =
new DatabaseEntry(searchName.getBytes("UTF-8"));
// Delete the first secondary record that uses "John Doe" as
// a key. This causes the primary record referenced by this secondary
// record to be deleted.
OperationStatus retVal = mySecondaryDatabase.delete(null, searchKey);
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="readSecondary.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="secondaryCursor.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Reading Secondary Databases </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> 
Using Secondary Cursors
</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,92 @@
<?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>Secondary Database Properties</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="indexes.html" title="Chapter 10. Secondary Databases" />
<link rel="previous" href="keyCreator.html" title="Implementing Key &#10; Creators&#10; &#10; " />
<link rel="next" href="readSecondary.html" title="Reading Secondary Databases" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Secondary Database Properties</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="keyCreator.html">Prev</a> </td>
<th width="60%" align="center">Chapter 10. Secondary Databases</th>
<td width="20%" align="right"> <a accesskey="n" href="readSecondary.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="secondaryProps"></a>Secondary Database Properties</h2>
</div>
</div>
<div></div>
</div>
<p>Secondary databases accept <tt class="classname">SecondaryConfig</tt>
objects. <tt class="classname">SecondaryConfig</tt> is a subclass of <tt class="classname">DatabaseConfig</tt>,
so it can manage all of the same properties as does <tt class="classname">DatabaseConfig</tt>.
See <a href="DBConfig.html">Database Properties</a> for more information.</p>
<p>In addition to the <tt class="classname">DatabaseConfig</tt> properties,
<tt class="classname">SecondaryConfig</tt> also allows you to manage the following properties:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">SecondaryConfig.setAllowPopulate()</tt>
</p>
<p>If true, the secondary database can be auto-populated. This means
that on open, if the secondary database is empty then the primary
database is read in its entirety and additions/modifications to the
secondary's records occur automatically.</p>
</li>
<li>
<p>
<tt class="methodname">SecondaryConfig.setKeyCreator()</tt>
</p>
<p>Identifies the key creator object to be used for secondary key
creation. See <a href="keyCreator.html">Implementing Key
<span>Creators</span>
</a>
for more information.</p>
</li>
</ul>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="keyCreator.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="readSecondary.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Implementing Key
Creators
 </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Reading Secondary Databases</td>
</tr>
</table>
</div>
</body>
</html>

102
docs/gsg/JAVA/simpleda.html Normal file
View File

@@ -0,0 +1,102 @@
<?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>SimpleDA.class</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="next" href="simpleput.html" title="Placing Objects in an Entity Store" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">SimpleDA.class</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="persist_access.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="simpleput.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="simpleda"></a>SimpleDA.class</h2>
</div>
</div>
<div></div>
</div>
<p>
As mentioned above, we organize our primary and
secondary indexes using a specialize data
accessor class. The main reason for this class
to exist is to provide convenient access to all
the indexes in use for our entity class (see
the previous section, <a href="persist_access.html#simpleentity">A Simple Entity Class</a>, for that
implementation).
</p>
<p>
For a description on retrieving primary and
secondary indexes under the DPL, see
<a href="persist_index.html">Working with Indices</a>
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;
public class SimpleDA {
// Open the indices
public SimpleDA(EntityStore store)
throws DatabaseException {
// Primary key for SimpleEntityClass classes
pIdx = store.getPrimaryIndex(
String.class, SimpleEntityClass.class);
// Secondary key for SimpleEntityClass classes
// Last field in the getSecondaryIndex() method must be
// the name of a class member; in this case, an
// SimpleEntityClass.class data member.
sIdx = store.getSecondaryIndex(
pIdx, String.class, "sKey");
}
// Index Accessors
PrimaryIndex&lt;String,SimpleEntityClass&gt; pIdx;
SecondaryIndex&lt;String,String,SimpleEntityClass&gt; sIdx;
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="persist_access.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="simpleput.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 5. Saving and Retrieving Objects </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Placing Objects in an Entity Store</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,174 @@
<?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>Retrieving Objects from an Entity Store</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="simpleput.html" title="Placing Objects in an Entity Store" />
<link rel="next" href="getmultiple.html" title="Retrieving Multiple Objects" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Retrieving Objects from an Entity Store</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="simpleput.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="getmultiple.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="simpleget"></a>Retrieving Objects from an Entity Store</h2>
</div>
</div>
<div></div>
</div>
<p>
You retrieve objects placed in an entity store by using
either the object's primary index, or the appropriate
secondary index if it exists. The following application
illustrates this by retrieving some of the objects that
we placed in an entity store in the previous section.
</p>
<p>
To begin, we import the Java classes that our example
needs. We also instantiate the private data members that we
require.
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import java.io.FileNotFoundException;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;
public class SimpleStoreGet {
private static File envHome = new File("./JEDB");
private Environment envmnt;
private EntityStore store;
private SimpleDA sda; </pre>
<p>
Next we create a method that simply opens our database
environment and entity store for us.
</p>
<pre class="programlisting"> // The setup() method opens the environment and store
// for us.
public void setup()
throws DatabaseException {
EnvironmentConfig envConfig = new EnvironmentConfig();
StoreConfig storeConfig = new StoreConfig();
envConfig.setAllowCreate(true);
storeConfig.setAllowCreate(true);
try {
// Open the environment and entity store
envmnt = new Environment(envHome, envConfig);
store = new EntityStore(envmnt, "EntityStore", storeConfig);
} catch (FileNotFoundException fnfe) {
System.err.println("setup(): " + fnfe.toString());
System.exit(-1);
}
} </pre>
<p>
We also need a method to close our environment and store.
</p>
<pre class="programlisting"> // Close our environment and store.
public void shutdown()
throws DatabaseException {
store.close();
envmnt.close();
} </pre>
<p>
Now we retrieve a few objects. To do this, we instantiate a
<tt class="classname">SimpleDA</tt> (see <a href="simpleda.html">SimpleDA.class</a>) class that we use to access
our primary and secondary indexes. Then we retrieve objects
based on a primary or secondary index value. And finally, we
display the retrieved objects.
</p>
<pre class="programlisting"> // Retrieve some SimpleEntityClass objects from the store.
private void run()
throws DatabaseException {
setup();
// Open the data accessor. This is used to store
// persistent objects.
sda = new SimpleDA(store);
// Instantiate and store some entity classes
SimpleEntityClass sec1 = sda.pIdx.get("keyone");
SimpleEntityClass sec2 = sda.pIdx.get("keytwo");
SimpleEntityClass sec4 = sda.sIdx.get("skeythree");
System.out.println("sec1: " + sec1.getpKey());
System.out.println("sec2: " + sec2.getpKey());
System.out.println("sec4: " + sec4.getpKey());
shutdown();
} </pre>
<p>
Finally, to complete our class, we need a
<tt class="methodname">main()</tt> method, which simply calls our
<tt class="methodname">run()</tt> method.
</p>
<pre class="programlisting"> // main
public static void main(String args[]) {
SimpleStoreGet ssg = new SimpleStoreGet();
try {
ssg.run();
} catch (DatabaseException dbe) {
System.err.println("SimpleStoreGet: " + dbe.toString());
dbe.printStackTrace();
} catch (Exception e) {
System.out.println("Exception: " + e.toString());
e.printStackTrace();
}
System.out.println("All done.");
}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="simpleput.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="getmultiple.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Placing Objects in an Entity Store </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Retrieving Multiple Objects</td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,224 @@
<?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>Placing Objects in an Entity Store</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="persist_access.html" title="Chapter 5. Saving and Retrieving Objects" />
<link rel="previous" href="simpleda.html" title="SimpleDA.class" />
<link rel="next" href="simpleget.html" title="Retrieving Objects from an Entity Store" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Placing Objects in an Entity Store</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="simpleda.html">Prev</a> </td>
<th width="60%" align="center">Chapter 5. Saving and Retrieving Objects</th>
<td width="20%" align="right"> <a accesskey="n" href="simpleget.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="simpleput"></a>Placing Objects in an Entity Store</h2>
</div>
</div>
<div></div>
</div>
<p>
In order to place an object in a DPL entity store,
you must:
</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>
Open the environment and store.
</p>
</li>
<li>
<p>
Instantiate the object.
</p>
</li>
<li>
<p>
Put the object to the store using the
<tt class="methodname">put()</tt> method
for the object's primary index.
</p>
</li>
</ol>
</div>
<p>
The following example uses the <tt class="classname">SimpleDA</tt>
class that we show in <a href="simpleda.html">SimpleDA.class</a> to put a
<tt class="classname">SimpleEntityClass</tt> object (see
<a href="persist_access.html#simpleentity">A Simple Entity Class</a>) to the
entity store.
</p>
<p>
To begin, we import the Java classes that our example
needs. We also instantiate the private data members that we
require.
</p>
<pre class="programlisting">package persist.gettingStarted;
import java.io.File;
import java.io.FileNotFoundException;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;
public class SimpleStorePut {
private static File envHome = new File("./JEDB");
private Environment envmnt;
private EntityStore store;
private SimpleDA sda; </pre>
<p>
Next we create a method that simply opens our database
environment and entity store for us.
</p>
<pre class="programlisting"> // The setup() method opens the environment and store
// for us.
public void setup()
throws DatabaseException {
EnvironmentConfig envConfig = new EnvironmentConfig();
StoreConfig storeConfig = new StoreConfig();
envConfig.setAllowCreate(true);
storeConfig.setAllowCreate(true);
try {
// Open the environment and entity store
envmnt = new Environment(envHome, envConfig);
store = new EntityStore(envmnt, "EntityStore", storeConfig);
} catch (FileNotFoundException fnfe) {
System.err.println("setup(): " + fnfe.toString());
System.exit(-1);
}
} </pre>
<p>
We also need a method to close our environment and store.
</p>
<pre class="programlisting"> // Close our environment and store.
public void shutdown()
throws DatabaseException {
store.close();
envmnt.close();
} </pre>
<p>
Now we need to create a method to actually write objects to our
store. This method creates a <tt class="classname">SimpleDA</tt>
object (see <a href="simpleda.html">SimpleDA.class</a> that we
will use to access our indexes. Then we instantiate a serious
of <tt class="classname">SimpleEntityClass</tt> (see <a href="persist_access.html#simpleentity">A Simple Entity Class</a>)
instances that we
will place in our store. Finally, we use our primary index
(obtained from the <tt class="classname">SimpleDA</tt> class
instance) to actually place these objects in our store.
</p>
<p>
In <a href="simpleget.html">Retrieving Objects from an Entity Store</a>
we show a class that is used to retrieve these objects.
</p>
<pre class="programlisting"> // Populate the entity store
private void run()
throws DatabaseException {
setup();
// Open the data accessor. This is used to store
// persistent objects.
sda = new SimpleDA(store);
// Instantiate and store some entity classes
SimpleEntityClass sec1 = new SimpleEntityClass();
SimpleEntityClass sec2 = new SimpleEntityClass();
SimpleEntityClass sec3 = new SimpleEntityClass();
SimpleEntityClass sec4 = new SimpleEntityClass();
SimpleEntityClass sec5 = new SimpleEntityClass();
sec1.setpKey("keyone");
sec1.setsKey("skeyone");
sec2.setpKey("keytwo");
sec2.setsKey("skeyone");
sec3.setpKey("keythree");
sec3.setsKey("skeytwo");
sec4.setpKey("keyfour");
sec4.setsKey("skeythree");
sec5.setpKey("keyfive");
sec5.setsKey("skeyfour");
sda.pIdx.put(sec1);
sda.pIdx.put(sec2);
sda.pIdx.put(sec3);
sda.pIdx.put(sec4);
sda.pIdx.put(sec5);
shutdown();
} </pre>
<p>
Finally, to complete our class, we need a
<tt class="methodname">main()</tt> method, which simply calls our
<tt class="methodname">run()</tt> method.
</p>
<pre class="programlisting"> // main
public static void main(String args[]) {
SimpleStorePut ssp = new SimpleStorePut();
try {
ssp.run();
} catch (DatabaseException dbe) {
System.err.println("SimpleStorePut: " + dbe.toString());
dbe.printStackTrace();
} catch (Exception e) {
System.out.println("Exception: " + e.toString());
e.printStackTrace();
}
System.out.println("All done.");
}
} </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="simpleda.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="persist_access.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="simpleget.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">SimpleDA.class </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Retrieving Objects from an Entity Store</td>
</tr>
</table>
</div>
</body>
</html>

424
docs/gsg/JAVA/usingDbt.html Normal file
View File

@@ -0,0 +1,424 @@
<?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>Reading and Writing Database Records</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
<link rel="up" href="DBEntry.html" title="Chapter 8. Database Records" />
<link rel="previous" href="DBEntry.html" title="Chapter 8. Database Records" />
<link rel="next" href="bindAPI.html" title="Using the BIND APIs" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Reading and Writing Database Records</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="DBEntry.html">Prev</a> </td>
<th width="60%" align="center">Chapter 8. Database Records</th>
<td width="20%" align="right"> <a accesskey="n" href="bindAPI.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="usingDbt"></a>Reading and Writing Database Records</h2>
</div>
</div>
<div></div>
</div>
<p>
When reading and writing database records, be aware that there are some
slight differences in behavior depending on whether your database supports duplicate
records. Two or more database records are considered to be duplicates of
one another if they share the same key. The collection of records
sharing the same key are called a <span class="emphasis"><em>duplicates set.</em></span>
<span>
In DB, a given key is stored only once for a single duplicates set.
</span>
</p>
<p>
By default, DB databases do
not support duplicate records. Where duplicate records are supported,
cursors (see below) are <span>typically</span> used
to access all of the records in the duplicates set.
</p>
<p>
DB provides two basic mechanisms for the storage and retrieval of database
key/data pairs:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
The
<tt class="methodname">Database.put()</tt>
and
<tt class="methodname">Database.get()</tt>
methods provide the easiest access for all non-duplicate records in the database.
These methods are described in this section.
</p>
</li>
<li>
<p>Cursors provide several methods for putting and getting database
records. Cursors and their database access methods are described in
<a href="Cursors.html">Using Cursors</a>.</p>
</li>
</ul>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="databaseWrite"></a>Writing Records to the Database</h3>
</div>
</div>
<div></div>
</div>
<p>
Records are stored in the database using whatever organization is
required by the access method that you have selected. In some cases (such as
BTree), records are stored in a sort order that you may want to define
(see <a href="btree.html#comparators">Setting Comparison Functions</a> for more information).
</p>
<p>
In any case, the mechanics of putting and getting database records do not
change once you have selected your access method, configured your
sorting routines (if any), and opened your database. From your
code's perspective, a simple database put and get is largely the
same no matter what access method you are using.
</p>
<p>You can use the following methods to put database records:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">Database.put()</tt>
</p>
<p>
Puts a database record into the database. If your database does not
support duplicate records, and if the provided key already exists in
the database, then the currently existing record is replaced with
the new data.
</p>
</li>
<li>
<p>
<tt class="methodname">Database.putNoOverwrite()</tt>
</p>
<p>
Disallows overwriting (replacing) an existing record in the
database. If the provided key already exists in the database,
then this method returns
<tt class="literal">OperationStatus.KEYEXIST</tt> even if
the database supports duplicates.
</p>
</li>
<li>
<p>
<tt class="methodname">Database.putNoDupData()</tt>
</p>
<p>
Puts a database record into the database. If the provided key
and data already exists in the database (that is, if you are
attempting to put a record that compares equally to an existing
record), then this returns
<tt class="literal">OperationStatus.KEYEXIST</tt>.
</p>
</li>
</ul>
</div>
<p>
When you put database records, you provide both the key and the data as
<tt class="classname">DatabaseEntry</tt> objects. This means you must
convert your key and data into a Java <tt class="literal">byte</tt> array. For
example:
</p>
<a id="java_dbt3"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.Database;
...
// Database opens omitted for clarity.
// Databases must NOT be opened read-only.
String aKey = "myFirstKey";
String aData = "myFirstData";
try {
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
myDatabase.put(null, theKey, theData);
} catch (Exception e) {
// Exception handling goes here
} </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="databaseRead"></a>Getting Records from the Database</h3>
</div>
</div>
<div></div>
</div>
<p>
The <tt class="classname">Database</tt> class provides several
methods that you can use to retrieve database records. Note that if your
database supports duplicate records, then these methods will only ever
return the first record in a duplicate set. For this reason, if your
database supports duplicates, you should use a cursor to retrieve
records from it. Cursors are described in <a href="Cursors.html">Using Cursors</a>.
</p>
<p>
You can use either of the following methods to retrieve records from the database:
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<tt class="methodname">Database.get()</tt>
</p>
<p>Retrieves the record whose key matches the key provided to the
method. If no records exists that uses the provided key, then
<tt class="literal">OperationStatus.NOTFOUND</tt> is returned.</p>
</li>
<li>
<p>
<tt class="methodname">Database.getSearchBoth()</tt>
</p>
<p>Retrieve the record whose key matches both the key and the data
provided to the method. If no record exists that uses the provided
key and data, then <tt class="literal">OperationStatus.NOTFOUND</tt> is
returned.</p>
</li>
</ul>
</div>
<p>Both the key and data for a database record are returned as
byte arrays in <tt class="classname">DatabaseEntry</tt> objects. These objects are
passed as parameter values to the <tt class="methodname">Database.get()</tt> method.
</p>
<p>In order to retrieve your data once <tt class="classname">Database.get()</tt>
has completed, you must retrieve the <tt class="literal">byte</tt> array stored
in the <tt class="classname">DatabaseEntry</tt> and then convert that
<tt class="literal">byte</tt> array back to the
appropriate datatype. For example:</p>
<a id="java_dbt4"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.Database;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;
...
Database myDatabase = null;
// Database opens omitted for clarity.
// Database may be opened read-only.
String aKey = "myFirstKey";
try {
// Create a pair of DatabaseEntry objects. theKey
// is used to perform the search. theData is used
// to store the data returned by the get() operation.
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
// Perform the get.
if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
// Recreate the data String.
byte[] retData = theData.getData();
String foundData = new String(retData, "UTF-8");
System.out.println("For key: '" + aKey + "' found data: '" +
foundData + "'.");
} else {
System.out.println("No record found for key '" + aKey + "'.");
}
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="recordDelete"></a>Deleting Records</h3>
</div>
</div>
<div></div>
</div>
<p>
You can use the
<tt class="methodname">Database.delete()</tt>
method to delete a record from the database. If your database supports
duplicate records, then all records associated with the provided key are
deleted. To delete just one record from a list of duplicates, use a
cursor. Cursors are described in <a href="Cursors.html">Using Cursors</a>.
</p>
<p>
You can also delete every record in the database by using
<tt class="methodname">Environment.truncateDatabase().</tt>
</p>
<p>For example:</p>
<a id="java_dbt5"></a>
<pre class="programlisting">package db.GettingStarted;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.Database;
...
Database myDatabase = null;
// Database opens omitted for clarity.
// Database can NOT be opened read-only.
try {
String aKey = "myFirstKey";
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
// Perform the deletion. All records that use this key are
// deleted.
myDatabase.delete(null, theKey);
} catch (Exception e) {
// Exception handling goes here
}</pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="datapersist"></a>Data Persistence</h3>
</div>
</div>
<div></div>
</div>
<p>
When you perform a database modification, your modification is made
in the in-memory cache. This means that your data modifications
are not necessarily flushed to disk, and so your data may not appear
in the database after an application restart.
</p>
<p>
Note that as a normal part of closing a database, its cache is
written to disk. However, in the event of an application or system
failure, there is no guarantee that your databases will close
cleanly. In this event, it is possible for you to lose data. Under
extremely rare circumstances, it is also possible for you to
experience database corruption.
</p>
<p>
Therefore, if you care if your data is durable across system
failures, and to guard against the rare possibility of
database corruption, you should use transactions to protect your
database modifications. Every time you commit a transaction, DB
ensures that the data will not be lost due to application or
system failure. Transaction usage is described in the
<span>
<i class="citetitle">Berkeley DB Getting Started with Transaction Processing</i> guide.
</span>
</p>
<p>
If you do not want to use transactions, then the assumption is that
your data is of a nature that it need not exist the next time your
application starts. You may want this if, for example, you are using
DB to cache data relevant only to the current application
runtime.
</p>
<p>
If, however, you are not using transactions for some reason and you
still want some guarantee that your database modifications are
persistent, then you should periodically
<span>run environment syncs.</span>
Syncs cause any dirty entries in the in-memory cache and the
operating system's file cache to be written to disk. As
such, they are quite expensive and you should use them sparingly.
</p>
<p>
Remember that by default a sync is performed any time a non-transactional
database is closed cleanly. (You can override this behavior by
specifying
<tt class="literal">true</tt>
on the call to
<span><tt class="methodname">Database.close()</tt>.)</span>
That said, you can manually run a sync by calling
<tt class="methodname">Database.sync().</tt>
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
If your application or system crashes and you are not using
transactions, then you should either discard and recreate your
databases, or verify them. You can verify a database using
<span>Database.verify().</span>
If your databases do not verify cleanly, use the
<span><b class="command">db_dump</b></span> command to salvage as much of the
database as is possible. Use either the <tt class="literal">-R</tt> or
<tt class="literal">-r</tt> command line options to control how
aggressive <span><b class="command">db_dump</b></span> should be when salvaging
your databases.
</p>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="DBEntry.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DBEntry.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="bindAPI.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 8. Database Records </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Using the BIND APIs</td>
</tr>
</table>
</div>
</body>
</html>