mirror of
https://github.com/berkeleydb/je.git
synced 2024-11-20 11:16:25 +00:00
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.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>
|