AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。

POJO を使用してデータをモデル化する

このガイドでは、Java Reactive Streams ドライバーを使用して、Plain Old Java Object(POJO)によってモデル化されたデータを保存および検索する方法を学ぶことができます。POJO は、ビジネス ロジックをデータ表現から分離するデータカプセル化によく使用されます。

Tip

POJO について詳しく学ぶには、Plain old Java object Wikipedia の記事を参照してください。

このガイドでは、次のタスクを実行する方法について説明しています。

  • POJO をシリアル化およびデシリアル化するようにドライバーを構成する

  • POJOでモデル化されたデータを使用してCRUD操作を実行する

重要

このガイドでは、サンプル カスタム サブスクリプション実装ガイドで説明されているカスタムSubscriber実装を使用します。

このガイドの例では、Person および Address POJO クラスを使用して、people という名前のサンプル コレクション内のドキュメントをモデル化します。

Person クラスは、人の名前、年齢、住所を保存します。このクラスには、次の定義があります。

import org.bson.types.ObjectId; public final class Person { private ObjectId id; private String name; private int age; private Address address; public Person() {} public Person(final String name, final int age, final Address address) { this.name = name; this.age = age; this.address = address; } public ObjectId getId() { return id; } public void setId(final ObjectId id) { this.id = id; } public String getName() { return name; } public void setName(final String name) { this.name = name; } public int getAge() { return age; } public void setAge(final int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(final Address address) { this.address = address; } @Override public String toString() { return "Person{" + "id='" + id + "'" + ", name='" + name + "'" + ", age=" + age + ", address=" + address + "}"; }}

Address クラスには、番地、都市、郵便番号が保存されます。このクラスには、次の定義があります。

public final class Address { private String street; private String city; private String zip; public Address() {} public Address(final String street, final String city, final String zip) { this.street = street; this.city = city; this.zip = zip; } public String getStreet() { return street; } public void setStreet(final String street) { this.street = street; } public String getCity() { return city; } public void setCity(final String city) { this.city = city; } public String getZip() { return zip; } public void setZip(final String zip) { this.zip = zip; } @Override public String toString() { return "Address{" + "street='" + street + "'" + ", city='" + city + "'" + ", zip='" + zip + "'" + "}"; }}

POJO クラスを定義する場合は、次の要件を満たしていることを確認してください。

  • POJO クラスは、インターフェースを実装したり、フレームワークからクラスを拡張したりすることはできません。

  • データを保存および検索するすべてのフィールドを含め、それらが static または transient としてマークされていないことを確認します。

  • JavaBean 命名規則に従って公開 getter メソッドまたは setter メソッドを含める場合、ドライバーはデータを直列化または逆直列化するときにそれらを呼び出します。公開フィールドの getter メソッドまたは setter メソッドを省略すると、ドライバーはそれらに直接アクセスするか、割り当てます。

Java Reactive Streams ドライバーで POJO を使用する前に、カスタム CodecRegistry を作成して POJO を直列化および非直列化するように構成する必要があります。次の手順は、CodecRegistry を作成してクライアント、データベース、またはコレクションに適用する方法を示します。

1

次のコードでは、PojoCodecProvider.Builder クラスの automatic(true) 設定を使用して、POJO コーデックを任意のクラスとそのプロパティに自動的に適用します。

CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
2

次のコードに示すように、デフォルトのコーデックレジストリと PojoCodecProvider を組み合わせた CodecRegistry を作成します。

CodecRegistry pojoCodecRegistry = fromRegistries( getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));

注意

レジストリは、要求されたクラスのコーデックを返すまで順にチェックされます。リストの先頭にデフォルトコーデック レジストリを含め、PojoCodecProvider を最後に含めます。これはほとんどのクラスのコーデックを提供できるためです。

3

カスタム CodecRegistry を使用するように MongoClient、MongoDatabase、または MongoCollection インスタンスを構成します。コーデックレジストリは、次のいずれかの方法で設定できます。

  1. MongoClientにCodecRegistryを設定します。

    MongoClientSettings settings = MongoClientSettings.builder() .codecRegistry(pojoCodecRegistry) .build();
  2. MongoDatabaseにCodecRegistryを設定します。

    MongoDatabase database = mongoClient.getDatabase("mydb").withCodecRegistry(pojoCodecRegistry);
  3. MongoCollectionにCodecRegistryを設定します。

    MongoCollection<org.bson.Document> rawCollection = database.getCollection("people").withCodecRegistry(pojoCodecRegistry);
4

次のコードに示すように、POJO クラスをドキュメント クラス パラメータとして getCollection() に渡し、それを MongoCollection インスタンスの型引数として指定します。

MongoCollection<Person> collection = database.getCollection("people", Person.class);

Person POJO を使用するようにドライバーを構成した後、POJO によってモデル化されたデータに対して CRUD 操作を実行できます。

コーデック レジストリは、不明なクラスの POJO Codecを自動的に作成するため、余計な構成なしで POJO をそのまま使用できます。

コレクションに単一のPersonを挿入するには、insertOne()メソッドを呼び出して結果をサブスクライブします。次の例では、adaという名前のPersonインスタンスをpeopleコレクションに挿入します。

Person ada = new Person("Ada Byron", 20, new Address("St James Square", "London", "W1"));collection.insertOne(ada).subscribe(new OperationSubscriber<InsertOneResult>());

複数のPersonインスタンスを挿入するには、insertMany()メソッドを呼び出し、インスタンスのリストを渡します。以下の例を参照してください。

List<Person> people = asList( new Person("Charles Babbage", 45, new Address("5 Devonshire Street", "London", "W11")), new Person("Alan Turing", 28, new Address("Bletchley Hall", "Bletchley Park", "MK12")), new Person("Timothy Berners-Lee", 61, new Address("Colehill", "Wimborne", null)));collection.insertMany(people).subscribe(new OperationSubscriber<InsertManyResult>());

コレクションをクエリするには、find() メソッドを使用します。特定の条件に一致するドキュメントを検索するには、find() メソッドにフィルター オブジェクトを渡すことができます。ドライバーには、フィルター オブジェクトの作成に使用できる Filters ヘルパー メソッドが用意されています。

重要

POJO をクエリする場合は、POJO プロパティ名ではなく、ドキュメント フィールド名に対してクエリを実行する必要があります。デフォルトでは同じですが、ドライバーが POJO プロパティ名をマップする方法を変更することも可能です。

フィルターに一致する最初の Person インスタンスを検索するには、find() 操作の結果に対して first() メソッドを呼び出します。

次の例では、address.city フィールドの値が "Wimborne" である最初の Person インスタンスを検索する:

collection.find(eq("address.city", "Wimborne")) .first() .subscribe(new PrintToStringSubscriber<>());

フィルターに一致するすべての Person インスタンスを検索するには、 find() メソッドを呼び出し、結果をサブスクライブします。

次の例では、age フィールドの値が 30 より大きいすべての Person インスタンスを検索する。

collection.find(gt("age", 30)).subscribe(new PrintToStringSubscriber<>());

コレクション内のドキュメントを更新するには、updateOne() メソッドと updateMany() メソッドを使用します。これらのメソッドに次のパラメータを渡します。

  • 更新するドキュメントを指定する フィルター オブジェクト。

  • 変更を指定するドキュメントを更新します。使用可能な演算子のリストを表示するには、MongoDB Server マニュアルの「更新演算子」を参照してください。

更新メソッドは、操作によって変更されたドキュメントの数など、操作に関する情報を提供する UpdateResult タイプを返します。

フィルターに一致する単一のPersonインスタンスを更新するには、updateOne()メソッドを使用します。

次の例では、"Ada Byron" という名前の Person を更新し、age フィールド値を 23 に、name フィールド値を "Ada Lovelace" に設定します。

collection.updateOne( eq("name", "Ada Byron"), combine(set("age", 23), set("name", "Ada Lovelace"))).subscribe(new OperationSubscriber<>());

フィルターに一致するすべてのPersonインスタンスを更新するには、 updateMany()メソッドを使用します。

次の例では、null 以外の zip 値を持つすべての Person インスタンスの zip フィールド値を null に設定します。

collection.updateMany(not(eq("zip", null)), set("zip", null)) .subscribe(new OperationSubscriber<>());

既存の Person インスタンスを完全に置き換えるには、replaceOne() メソッドを使用します。

次の例では、name フィールド値が "Ada Lovelace" の Person インスタンスを、ada 変数で参照される Person に置き換えます。

collection.replaceOne(eq("name", "Ada Lovelace"), ada) .subscribe(new OperationSubscriber<>());

コレクションからドキュメントを削除するには、deleteOne() メソッドと deleteMany() メソッドを使用します。削除するドキュメントに一致するようにフィルター オブジェクトを渡します。

削除メソッドでは、削除されたドキュメント数など操作に関する情報を提供するDeleteResultタイプが返されます。

フィルターに一致する単一のPersonを削除するには、 deleteOne()メソッドを使用します。

次の例では、address.city フィールドの値が "Wimborne" である 1 つの Person インスタンスを削除します。

collection.deleteOne(eq("address.city", "Wimborne")) .subscribe(new OperationSubscriber<>());

フィルターに一致するすべてのPersonインスタンスを削除するには、deleteMany()メソッドを使用します。

次の例では、 address.cityフィールドの値が "London"であるすべての Personインスタンスを削除しています。

collection.deleteMany(eq("address.city", "London")) .subscribe(new OperationSubscriber<>());

このガイドで述べられている CRUD 操作の詳細については、CRUD 操作セクションを参照してください。

このガイドで言及されているメソッドとクラスについて詳しくは、次の API ドキュメントを参照してください。