MongoTemplateを利用したMongoDB操作
では、ここからは実際にMongoDBへのデータの登録や検索を行っていきます。まずはMongoDBのドキュメントを表すクラスを用意します。今回の例では、Personというシンプルなクラスを用意します。
public class Person {
private String id;
private String name;
private int age;
Person(String name, int age){
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
オブジェクトとドキュメントのマッピングについて
Spring Data MongoDBでは、ドキュメントを表すクラスを定義するだけでMongoDBのコレクションとJavaのオブジェクトが一定のルールに従ってマッピングされます。クラスのフィールドはそのままドキュメントのフィールド名になります。
特に知っておく必要があるのは、MongoDBのドキュメントにおける"_id"のマッピングルールです。MongoDBではすべてのドキュメントで"_id"というフィールドが必要になります。この"_id"フィールドがどのようにJavaクラスにマッピングされるかは以下のようになります。
- @Id(org.springframework.data.annotation.Id)というアノテーションが付与されたフィールドもしくはプロパティ
- "id"という名称のフィールドもしくはプロパティ
加えて前回記事で説明したように"_id"の型はObjectIdです。マッピング時の”_id”フィールドの型の変換は、Javaクラスで"id"という名称のフィールドがString型もしくはBigInteger型で宣言されている場合、"_id"フィールドの値は自動的に変換されます。今回サンプルとして用意したPersonクラスは"id"という名称のプロパティをString型で宣言しているので、@Idアノテーションを付与しなくても、ドキュメントの"_id"フィールドに格納されている値がマッピングされます。
コレクション名は、標準ではクラス名の先頭1文字を小文字にしたものになります。クラス名と実際のコレクション名が異なる場合など自動で変換させたくない場合は、クラスに対して@Documentアノテーションを利用して対応するコレクション名を指定します。
ドキュメントの作成
ドキュメントの作成は以下のコードのようになります。なお、コレクションの作成を明示的には行っていませんが、MongoDBのシェルを利用する場合と同様に、存在しないコレクションが指定された場合は自動で作成されます。今回は先ほど用意したPersonクラスを使って処理を行うため、最初に処理を実行したタイミングで"person"コレクションが作成されます。
では、早速Personクラスに値をセットしてMongoDBへと保存する処理を見ていきます。
public class InsertSample {
public static void main(String[] args){
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MongoTemplate mongoTemplate = ctx.getBean(MongoTemplate.class);
Person person = new Person("John",25);
mongoTemplate.insert(person);
}
}
まず、先ほど作成したコンフィグレーションクラスであるAppConfigを指定して、アプリケーションコンテキストを取得します。続けて、AppConfig内でBeanとして登録したMongoTemplateを取得します。以降はこのMongoTemplateを使って処理を行っていきます。
Personオブジェクトを作成し、値をセットした上でPersonオブジェクトを引数としてMongoTemplateに用意されているinsertメソッドを実行しています。
なお、MongoTemplateでは、MongoDBで用意されているinsertなどのメソッドが、ほぼ同名のメソッドとして定義されています。insertメソッドではモデルとなるオブジェクトを引数に取るだけでなく、ドキュメントの作成先となるコレクション名を指定することも可能です。今回のようにコレクション名を指定しない場合は、引数に指定したオブジェクトの型名を元にコレクション名が決定されます。
では早速実行してみてください。その後、実際にドキュメントが作成されたかMongoシェルから確認をしてみます。
$ mongo example
MongoDB shell version: 2.2.2
connecting to: example
> db.person.find()
{ "_id" : ObjectId("512d6d313004e4722d2c668f"), "_class" : "org.sample.mongodb.Person", "name" : "John", "age" : 25 }
>
コードでは"_id"フィールドの値をセットしていませんが、その場合自動的に値がセットされて保存されます。
ドキュメントの参照
続いてドキュメントの参照(検索)を行ってみます。MongoDBでは多種多様なクエリーがサポートされていますが、Spring Data MongoDBでもその多くがサポートされています。まずは、簡単に特定のコレクションに含まれる全ドキュメントを取得してみます。
public class FindSample {
public static void main(String[] args){
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MongoTemplate mongoTemplate = ctx.getBean(MongoTemplate.class);
List<Person> persons = mongoTemplate.findAll(Person.class);
for(Person person : persons){
System.out.println("id : " + person.getId());
System.out.println("name : " + person.getName());
System.out.println("age : " + person.getAge());
}
}
}
findAllメソッドを利用することで、特定のコレクションに含まれる全ドキュメントの取得が行えます。コレクションの指定は、マップ先となるJavaクラスを指定するだけでも標準の変換ルールに則って行えますが、マップ先のJavaクラスの指定に加えて文字列で指定することも可能です。メソッドの戻り値は、MongoDBのドキュメントを変換したJavaオブジェクトのリストです。
続けて検索条件を指定してドキュメントの取得を行います。Spring Data MongoDBでは、クエリー条件をorg.springframework.data.mongodb.core.query.Query(以下、Query)とorg.springframework.data.mongodb.core.query.Criteria(以下、Criteria)を使って表現します。実際にはCriteriaを利用して組み立てた検索条件をQueryに追加し、findメソッドの引数としてQueryを指定することで行います。
public class FindSample {
public static void main(String[] args){
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MongoTemplate mongoTemplate = ctx.getBean(MongoTemplate.class);
List<Person> persons = mongoTemplate.find(new Query(Criteria.where("name").is("John")), Person.class);
for(Person person : persons){
System.out.println("id : " + person.getId());
System.out.println("name : " + person.getName());
System.out.println("age : " + person.getAge());
}
}
}
Criteriaクラスは、MongoDBがサポートするさまざまなクエリー用オペレータをメソッドとしてサポートしています。また、メソッドチェイン方式の実装が行われているため、直感的かつ流れるようなCriteriaの組立が可能です。例えば先ほどの条件にand条件としてageが25であることを指定する場合は、以下のようになります。
List<Person> persons = mongoTemplate.find(new Query(Criteria.where("name").is("John").and("age").is(25)), Person.class);
この他にも、MongoDBで用意されている$ltや$gtなどのオペレータが、Criteriaクラスのメソッドとして利用可能です。
また、他にもfindOneやfindByIdといったメソッドが用意されています。これらの基本的な使い方はfindと同様ですが、結果がリストではなくマッチしたドキュメントをマッピングしたオブジェクトが返ってくる点が異なります。
