MapDBのガイド

1. 前書き

この記事では、* http://www.mapdb.org/ [MapDB] library –コレクションのようなAPIを介してアクセスされる組み込みデータベースエンジンを見ていきます。*
まず、データベースの構成、オープン、管理に役立つコアクラス__DB __and __DBMaker __を調査します。 次に、データを保存および取得するMapDBデータ構造のいくつかの例に飛び込みます。
最後に、MapDBを従来のデータベースおよびJavaコレクションと比較する前に、インメモリモードのいくつかを見ていきます。

2. * MapDBにデータを保存する*

最初に、このチュートリアル全体で常に使用する2つのクラスを紹介しましょう。__DB __and __DBMaker。 __ ** _DB_クラスは開いているデータベースを表します。**そのメソッドは、ストレージコレクションを作成および閉じてデータベースレコードを処理するアクションを呼び出し、トランザクションイベントを処理します。
  • _DBMaker_は、データベースの構成、作成、およびオープンを処理します。*構成の一部として、メモリ内またはファイルシステム上でデータベースをホストすることを選択できます。

2.1. 簡単な_HashMap_の例

これがどのように機能するかを理解するために、メモリに新しいデータベースをインスタンス化しましょう。
まず、__ DBMaker __classを使用して新しいメモリ内データベースを作成しましょう。
DB db = DBMaker.memoryDB().make();
__DB __objectを起動して実行したら、それを使用して__HTreeMap __を構築し、データベースレコードを操作できます。
String welcomeMessageKey = "Welcome Message";
String welcomeMessageString = "Hello Baeldung!";

HTreeMap myMap = db.hashMap("myMap").createOrOpen();
myMap.put(welcomeMessageKey, welcomeMessageString);
__HTreeMap ___はMapDBの__HashMap ___implementationです。 データベースにデータがあるので、__ get __methodを使用してデータを取得できます。
String welcomeMessageFromDB = (String) myMap.get(welcomeMessageKey);
assertEquals(welcomeMessageString, welcomeMessageFromDB);
最後に、データベースの作成が完了したので、データベースを閉じて、さらなる突然変異を避ける必要があります。
db.close();
メモリではなくファイルにデータを保存するには、_DB_オブジェクトのインスタンス化の方法を変更するだけです。
DB db = DBMaker.fileDB("file.db").make();
上記の例では、型パラメーターを使用していません。 その結果、特定のタイプで動作するように結果をキャストすることに固執しています。 次の例では、__Serializers __を導入して、キャストの必要性を排除します。

2.2. コレクション

  • MapDBにはさまざまなコレクションタイプが含まれています。*デモンストレーションのために、a__NavigableSet_を使用してデータベースにデータを追加および取得します。

    __DB __objectの簡単なインスタンス化から始めましょう。
DB db = DBMaker.memoryDB().make();
次に、_NavigableSet_を作成しましょう。
NavigableSet<String> set = db
  .treeSet("mySet")
  .serializer(Serializer.STRING)
  .createOrOpen();
ここで、_serializer_は、データベースからの入力データが_String_オブジェクトを使用してシリアライズおよびデシリアライズされるようにします。
次に、いくつかのデータを追加しましょう。
set.add("Baeldung");
set.add("is awesome");
次に、2つの異なる値がデータベースに正しく追加されたことを確認します。
assertEquals(2, set.size());
最後に、これはセットなので、重複する文字列を追加し、データベースにまだ2つの値しか含まれていないことを確認しましょう。
set.add("Baeldung");

assertEquals(2, set.size());

2.3. トランザクション

従来のデータベースと同様に、* __ DB __classクラスは、データベースに追加するデータを__commit __and __rollback ___するメソッドを提供します。
この機能を有効にするには、__transactionEnable __methodで__DB __を初期化する必要があります。
DB db = DBMaker.memoryDB().transactionEnable().make();
次に、簡単なセットを作成し、データを追加して、データベースにコミットします。
NavigableSet<String> set = db
  .treeSet("mySet")
  .serializer(Serializer.STRING)
  .createOrOpen();

set.add("One");
set.add("Two");

db.commit();

assertEquals(2, set.size());
次に、データベースに3番目のコミットされていない文字列を追加しましょう。
set.add("Three");

assertEquals(3, set.size());
データに満足できない場合は、_DBのrollback_メソッドを使用してデータをロールバックできます。
db.rollback();

assertEquals(2, set.size());

2.4. シリアライザー

MapDBは、さまざまなhttps://jankotek.gitbooks.io/mapdb/content/htreemap/#serializers [コレクション内のデータを処理するシリアライザー]を提供します。 最も重要な構築パラメーターは名前で、__ DB __object内の個々のコレクションを識別します。
HTreeMap<String, Long> map = db.hashMap("indentification_name")
  .keySerializer(Serializer.STRING)
  .valueSerializer(Serializer.LONG)
  .create();
シリアル化が推奨されますが、これはオプションであり、スキップできます。 ただし、これにより一般的なシリアル化プロセスが遅くなることに注意してください。

3. HTreeMap

MapDBの* __ HTreeMap ___は、データベースを操作するための__HashMap __and __HashSet __collectionsを提供します。* _HTreeMap_は、セグメント化されたハッシュツリーであり、固定サイズのハッシュテーブルを使用しません。 代わりに、自動拡張インデックスツリーを使用し、テーブルが成長してもすべてのデータを再ハッシュしません。 さらに、* __ HTreeMap ___はスレッドセーフであり、複数のセグメントを使用した並列書き込みをサポートしています。*
まず、キーと値の両方に_String_を使用する単純な__HashMap __をインスタンス化します。
DB db = DBMaker.memoryDB().make();

HTreeMap<String, String> hTreeMap = db
  .hashMap("myTreeMap")
  .keySerializer(Serializer.STRING)
  .valueSerializer(Serializer.STRING)
  .create();
上記では、キーと値に別々の__serializers __を定義しました。 __HashMap __が作成されたので、__ put __methodを使用してデータを追加しましょう。
hTreeMap.put("key1", "value1");
hTreeMap.put("key2", "value2");

assertEquals(2, hTreeMap.size());
__ObjectのhashCode __methodで__HashMap __worksとして、同じキーを使用してデータを追加すると、値が上書きされます。
hTreeMap.put("key1", "value3");

assertEquals(2, hTreeMap.size());
assertEquals("value3", hTreeMap.get("key1"));

4. SortedTableMap

MapDBの* __ SortedTableMap ___は、固定サイズのテーブルにキーを格納し、検索にバイナリ検索を使用します。* *準備が完了すると、マップは読み取り専用になります*
__SortedTableMapの作成とクエリのプロセスを見ていきましょう。 __まず、データを保持するメモリマップボリュームと、データを追加するシンクを作成します。 ボリュームの最初の呼び出しで、読み取り専用フラグを_false_に設定し、ボリュームに書き込みができることを確認します。
String VOLUME_LOCATION = "sortedTableMapVol.db";

Volume vol = MappedFileVol.FACTORY.makeVolume(VOLUME_LOCATION, false);

SortedTableMap.Sink<Integer, String> sink =
  SortedTableMap.create(
    vol,
    Serializer.INTEGER,
    Serializer.STRING)
    .createFromSink();
次に、データを追加し、シンクで__create ___methodを呼び出してマップを作成します。
for(int i = 0; i < 100; i++){
  sink.put(i, "Value " + Integer.toString(i));
}

sink.create();
マップが存在するので、読み取り専用ボリュームを定義し、_SortedTableMapのopen_メソッドを使用してマップを開くことができます。
Volume openVol = MappedFileVol.FACTORY.makeVolume(VOLUME_LOCATION, true);

SortedTableMap<Integer, String> sortedTableMap = SortedTableMap
  .open(
    openVol,
    Serializer.INTEGER,
    Serializer.STRING);

assertEquals(100, sortedTableMap.size());

4.1. バイナリ検索

先に進む前に、__SortedTableMap ___がバイナリ検索をどのように利用するかをより詳しく理解しましょう。
_SortedTableMap_はストレージをページに分割し、各ページにはキーと値で構成される複数のノードが含まれます。 これらのノード内には、Javaコードで定義したキーと値のペアがあります。
_SortedTableMap_は、3つのバイナリ検索を実行して正しい値を取得します。
  1. 各ページのキーは、ヒープ上の配列に格納されます。 The
    _SortedTableMap_は、バイナリ検索を実行して正しいページを見つけます。

  2. 次に、ノード内の各キーに対して圧縮解除が行われます。 バイナリ検索
    キーに従って正しいノードを確立します。

  3. 最後に、_SortedTableMap_はノード内のキーを検索します
    正しい値を見つけます。

5. インメモリーモード

MapDBは* 3種類のメモリ内ストア*を提供します。各モードを簡単に見て、動作を理解し、その利点を調べてみましょう。

5.1. オンヒープ

オンヒープモードは、オブジェクトを単純なJavaコレクション_Map_に格納します。*シリアル化を使用せず、小さなデータセットに対して非常に高速です。 *
ただし、データはヒープに格納されるため、データセットはガベージコレクション(GC)によって管理されます。 GCの期間はデータセットのサイズとともに増加し、パフォーマンスが低下します。
オンヒープモードを指定する例を見てみましょう。
DB db = DBMaker.heapDB().make();

5.2. バイト[]

2番目のストアタイプは、バイト配列に基づいています。 このモードでは、*データはシリアル化され、最大1MBのサイズの配列に格納されます*
これはデフォルトで推奨されており、「link:#db [_Hello Baeldung'_ example]」で使用されています。
DB db = DBMaker.memoryDB().make();

5.3. _ DirectByteBuffer _

最終ストアは、Java 1.4で導入された_DirectByteBuffer._ Directメモリに基づいており、Javaヒープではなくネイティブメモリにデータを直接渡すことができます。 その結果、データは*完全にオフヒープに保存されます*。
このタイプのストアを呼び出すには:
DB db = DBMaker.memoryDirectDB().make();

6. MapDBを選ぶ理由

それでは、なぜMapDBを使用するのですか?

6.1. MapDBと従来のデータベース

MapDBは、わずか数行のJavaコードで構成された多数のデータベース機能を提供します。 MapDBを使用すると、プログラムを機能させるために必要なさまざまなサービスや接続のセットアップにしばしば時間がかかることを回避できます。
さらに、MapDBを使用すると、Javaコレクションに精通したデータベースの複雑さにアクセスできます。 MapDBを使用すると、SQLが不要になり、簡単な__get __method呼び出しでレコードにアクセスできます。

6.2. MapDBとシンプルなJavaコレクション

Javaコレクションは、実行が停止するとアプリケーションのデータを永続化しません。 MapDBは、Javaコレクションタイプのユーティリティを維持しながら、アプリケーション内のデータを迅速かつ簡単に永続化できる、シンプルで柔軟なプラグ可能なサービスを提供します。

7. 結論

この記事では、MapDBの組み込みデータベースエンジンとコレクションフレームワークについて詳しく説明しました。
まず、データベースの構成、オープン、管理を行うコアクラス__DB _と_ DBMaster _を確認しました。 次に、MapDBがレコードを操作するために提供するデータ構造の例をいくつか見ていきました。 最後に、従来のデータベースやJavaコレクションに対するMapDBの利点を調べました。
いつものように、サンプルコードはhttps://github.com/eugenp/tutorials/tree/master/libraries-2[over on GitHub]で入手できます。