Overview
このガイドでは、Java Reactive Streams ドライバーを使用して、Plain Old Java Object(POJO)によってモデル化されたデータを保存および検索する方法を学ぶことができます。POJO は、ビジネス ロジックをデータ表現から分離するデータカプセル化によく使用されます。
Tip
POJO について詳しく学ぶには、Plain old Java object Wikipedia の記事を参照してください。
このガイドでは、次のタスクを実行する方法について説明しています。
POJO をシリアル化およびデシリアル化するようにドライバーを構成する
POJOでモデル化されたデータを使用してCRUD操作を実行する
重要
このガイドでは、サンプル カスタム サブスクリプション実装ガイドで説明されているカスタムSubscriber実装を使用します。
サンプル POJO
このガイドの例では、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; } 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; } public String toString() { return "Address{" + "street='" + street + "'" + ", city='" + city + "'" + ", zip='" + zip + "'" + "}"; } }
POJO クラスを定義する場合は、次の要件を満たしていることを確認してください。
POJO クラスは、インターフェースを実装したり、フレームワークからクラスを拡張したりすることはできません。
データを保存および検索するすべてのフィールドを含め、それらが
staticまたはtransientとしてマークされていないことを確認します。JavaBean 命名規則に従って公開 getter メソッドまたは setter メソッドを含める場合、ドライバーはデータを直列化または逆直列化するときにそれらを呼び出します。公開フィールドの getter メソッドまたは setter メソッドを省略すると、ドライバーはそれらに直接アクセスするか、割り当てます。
POJO のドライバーの設定
Java Reactive Streams ドライバーで POJO を使用する前に、カスタム CodecRegistry を作成して POJO を直列化および非直列化するように構成する必要があります。次の手順は、CodecRegistry を作成してクライアント、データベース、またはコレクションに適用する方法を示します。
CodecRegistryを作成します。
次のコードに示すように、デフォルトのコーデックレジストリと PojoCodecProvider を組み合わせた CodecRegistry を作成します。
CodecRegistry pojoCodecRegistry = fromRegistries( getDefaultCodecRegistry(), fromProviders(pojoCodecProvider) );
注意
レジストリは、要求されたクラスのコーデックを返すまで順にチェックされます。リストの先頭にデフォルトコーデック レジストリを含め、PojoCodecProvider を最後に含めます。これはほとんどのクラスのコーデックを提供できるためです。
CodecRegistryを適用します。
カスタム CodecRegistry を使用するように MongoClient、MongoDatabase、または MongoCollection インスタンスを構成します。コーデックレジストリは、次のいずれかの方法で設定できます。
MongoClientにCodecRegistryを設定します。MongoClientSettings settings = MongoClientSettings.builder() .codecRegistry(pojoCodecRegistry) .build(); MongoDatabaseにCodecRegistryを設定します。MongoDatabase database = mongoClient.getDatabase("mydb").withCodecRegistry(pojoCodecRegistry); MongoCollectionにCodecRegistryを設定します。MongoCollection<org.bson.Document> rawCollection = database.getCollection("people").withCodecRegistry(pojoCodecRegistry);
CRUD 操作を実行
Person POJO を使用するようにドライバーを構成した後、POJO によってモデル化されたデータに対して CRUD 操作を実行できます。
Insert Data
コーデック レジストリは、不明なクラスの 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 プロパティ名をマップする方法を変更することも可能です。
Retrieve One
フィルターに一致する最初の Person インスタンスを検索するには、find() 操作の結果に対して first() メソッドを呼び出します。
次の例では、address.city フィールドの値が "Wimborne" である最初の Person インスタンスを検索する:
collection.find(eq("address.city", "Wimborne")) .first() .subscribe(new PrintToStringSubscriber<>());
Person{id='...', name='Timothy Berners-Lee', age=61, address=Address{street='Colehill', city='Wimborne', zip='null'}}
複数検索する
フィルターに一致するすべての Person インスタンスを検索するには、 find() メソッドを呼び出し、結果をサブスクライブします。
次の例では、age フィールドの値が 30 より大きいすべての Person インスタンスを検索する。
collection.find(gt("age", 30)).subscribe(new PrintToStringSubscriber<>());
Person{id='...', name='Charles Babbage', age=45, address=Address{street='5 Devonshire Street', city='London', zip='W11'}} Person{id='...', name='Timothy Berners-Lee', age=61, address=Address{street='Colehill', city='Wimborne', zip='null'}}
データの更新
コレクション内のドキュメントを更新するには、updateOne() メソッドと updateMany() メソッドを使用します。これらのメソッドに次のパラメータを渡します。
更新するドキュメントを指定する フィルター オブジェクト。
変更を指定するドキュメントを更新します。使用可能な演算子のリストを表示するには、MongoDB Server マニュアルの「更新演算子」を参照してください。
更新メソッドは、操作によって変更されたドキュメントの数など、操作に関する情報を提供する UpdateResult タイプを返します。
更新 1
フィルターに一致する単一の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<>());
replaceOne
既存の Person インスタンスを完全に置き換えるには、replaceOne() メソッドを使用します。
次の例では、name フィールド値が "Ada Lovelace" の Person インスタンスを、ada 変数で参照される Person に置き換えます。
collection.replaceOne(eq("name", "Ada Lovelace"), ada) .subscribe(new OperationSubscriber<>());
データの削除
コレクションからドキュメントを削除するには、deleteOne() メソッドと deleteMany() メソッドを使用します。削除するドキュメントに一致するようにフィルター オブジェクトを渡します。
削除メソッドでは、削除されたドキュメント数など操作に関する情報を提供するDeleteResultタイプが返されます。
deleteOne
フィルターに一致する単一の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 ドキュメント
このガイドで言及されているメソッドとクラスについて詳しくは、次の API ドキュメントを参照してください。