mirror of
https://github.com/berkeleydb/je.git
synced 2024-11-15 01:46:24 +00:00
424 lines
16 KiB
HTML
424 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.73.2" />
|
||
<link rel="start" href="index.html" title="Getting Started with Berkeley DB Java Edition" />
|
||
<link rel="up" href="DBEntry.html" title="Chapter 8. Database Records" />
|
||
<link rel="prev" href="DBEntry.html" title="Chapter 8. Database Records" />
|
||
<link rel="next" href="timetolive.html" title="Using Time to Live" />
|
||
</head>
|
||
<body>
|
||
<div xmlns="" class="navheader">
|
||
<div class="libver">
|
||
<p>Library Version 12.2.7.5</p>
|
||
</div>
|
||
<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="timetolive.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 class="toc">
|
||
<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>
|
||
</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>
|
||
|
||
|
||
</p>
|
||
<p>
|
||
By default, JE databases do
|
||
not support duplicate records. Where duplicate records are supported,
|
||
cursors (see below) are used
|
||
to access all of the records in the duplicates set.
|
||
</p>
|
||
<p>
|
||
JE provides two basic mechanisms for the storage and retrieval of database
|
||
key/data pairs:
|
||
</p>
|
||
<div class="itemizedlist">
|
||
<ul type="disc">
|
||
<li>
|
||
<p>
|
||
The
|
||
<code class="methodname">Database.put()</code>
|
||
|
||
|
||
and
|
||
<code class="methodname">Database.get()</code>
|
||
|
||
|
||
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 class="xref" href="Cursors.html" title="Chapter 9. Using Cursors">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>
|
||
<p>
|
||
Database records are stored in the internal BTree based on
|
||
whatever sorting routine is available to the database. Records are
|
||
sorted first by their key. If the database supports duplicate records,
|
||
then the records for a specific key are sorted by their data.
|
||
</p>
|
||
<p>
|
||
By default, JE sorts both keys and the data portion of duplicate
|
||
records using unsigned byte-by-byte
|
||
lexicographic comparisons. This default comparison works well for the
|
||
majority of cases. However, in some case performance benefits can be
|
||
realized by overriding the default comparison routine. See <a class="xref" href="comparator.html" title="Using Comparators">Using Comparators</a> for more information.
|
||
</p>
|
||
<p>You can use the following methods to put database records:</p>
|
||
<div class="itemizedlist">
|
||
<ul type="disc">
|
||
<li>
|
||
<p>
|
||
<code class="methodname">Database.put()</code>
|
||
</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>
|
||
<p>
|
||
Be aware that version of this method exists which accepts a
|
||
<code class="classname">Put</code> enum. If <code class="literal">Put.OVERWRITE</code>
|
||
is provided, then existing database records are
|
||
overwritten. If <code class="literal">Put.NO_OVERWRITE</code> is
|
||
provided, then existing records will not be overwritten.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<code class="methodname">Database.putNoOverwrite()</code>
|
||
</p>
|
||
<p>
|
||
Disallows overwriting (replacing) an existing record in the
|
||
database. If the provided key already exists in the database,
|
||
then this method returns
|
||
<code class="literal">OperationStatus.KEYEXIST</code> even if
|
||
the database supports duplicates.
|
||
</p>
|
||
<span>
|
||
|
||
</span>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<code class="methodname">Database.putNoDupData()</code>
|
||
</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
|
||
<code class="literal">OperationStatus.KEYEXIST</code>.
|
||
</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<p>
|
||
When you put database records, you provide both the key and the data as
|
||
<code class="classname">DatabaseEntry</code> objects. This means you must
|
||
convert your key and data into a Java <code class="literal">byte</code> array. For
|
||
example:
|
||
</p>
|
||
<a id="je_dbt3"></a>
|
||
<pre class="programlisting">package je.gettingStarted;
|
||
|
||
import com.sleepycat.je.Database;
|
||
import com.sleepycat.je.DatabaseEntry;
|
||
|
||
...
|
||
|
||
// Environment and database opens omitted for clarity.
|
||
// Environment and database 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>
|
||
<p>
|
||
The <code class="classname">Database</code> 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 class="xref" href="Cursors.html" title="Chapter 9. Using Cursors">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>
|
||
<code class="methodname">Database.get()</code>
|
||
</p>
|
||
<p>Retrieves the record whose key matches the key provided to the
|
||
method. If no records exists that uses the provided key, then
|
||
<code class="literal">OperationStatus.NOTFOUND</code> is returned.</p>
|
||
<span>
|
||
|
||
</span>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<code class="methodname">Database.getSearchBoth()</code>
|
||
</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 <code class="literal">OperationStatus.NOTFOUND</code> is
|
||
returned.</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<p>Both the key and data for a database record are returned as
|
||
byte arrays in <code class="classname">DatabaseEntry</code> objects. These objects are
|
||
passed as parameter values to the <code class="methodname">Database.get()</code> method.
|
||
</p>
|
||
<p>In order to retrieve your data once <code class="classname">Database.get()</code>
|
||
has completed, you must retrieve the <code class="literal">byte</code> array stored
|
||
in the <code class="classname">DatabaseEntry</code> and then convert that
|
||
<code class="literal">byte</code> array back to the
|
||
appropriate datatype. For example:</p>
|
||
<a id="je_dbt4"></a>
|
||
<pre class="programlisting">package je.gettingStarted;
|
||
|
||
import com.sleepycat.je.Database;
|
||
import com.sleepycat.je.DatabaseEntry;
|
||
import com.sleepycat.je.LockMode;
|
||
import com.sleepycat.je.OperationStatus;
|
||
|
||
...
|
||
|
||
// Environment and database opens omitted for clarity.
|
||
// Environment and 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>
|
||
<p>
|
||
|
||
You can use the
|
||
<code class="methodname">Database.delete()</code>
|
||
|
||
|
||
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 class="xref" href="Cursors.html" title="Chapter 9. Using Cursors">Using Cursors</a>.
|
||
|
||
</p>
|
||
<p>
|
||
You can also delete every record in the database by using
|
||
<code class="methodname">Environment.truncateDatabase().</code>
|
||
|
||
|
||
</p>
|
||
<p>For example:</p>
|
||
<a id="je_dbt5"></a>
|
||
<pre class="programlisting">package je.gettingStarted;
|
||
|
||
import com.sleepycat.je.Database;
|
||
import com.sleepycat.je.DatabaseEntry;
|
||
|
||
...
|
||
|
||
// Environment and database opens omitted for clarity.
|
||
// Environment and 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>
|
||
<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>
|
||
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, JE
|
||
ensures that the data will not be lost due to application or
|
||
system failure. Transaction usage is described in the
|
||
<span>
|
||
<em class="citetitle">Berkeley DB, Java Edition Getting Started with Transaction Processing</em> 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
|
||
JE 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>
|
||
Note that by default, a sync is run every time you close an environment.
|
||
You can also run a sync by calling the <code class="methodname">Environment.sync()</code>
|
||
method.
|
||
|
||
|
||
|
||
</p>
|
||
<p>
|
||
For a brief description of how JE manages its data in the cache
|
||
and in the log files, and how sync works, see <a class="xref" href="backuprestore.html#databaselogs" title="Databases and Log Files">Databases and Log Files</a>.
|
||
</p>
|
||
</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="timetolive.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 Time to Live</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</body>
|
||
</html>
|