425 lines
16 KiB
HTML
425 lines
16 KiB
HTML
<?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>
|