Java+MongoDB+Morphiaを使ってみる。その1

Java+MongoDB+Morphiaを使ってMongoDBを操作したいと思います。

MongoDBの操作には、公式のJavaドライバーを使用する事ができます。

公式ドライバーでは、BasicDBObjectというMap実装を使用しているが、POJOを保存したり取得できた方がメリットが大きい。

そこでMorphiaを使ってみる。

Morphiaは、この役割を果たすために、Javaドライバーのラッパーを提供しています。

早速使ってみます。

Morphiaのダウンロード

Morphiaのダウンロード

2011年6月21日の最新版、morphia-1.00-SNAPSHOT.jarを取得します。

せっかくなので、QuickStartを利用してみます。

QuickStart

test
 ∟dto
   ∟Address.java
   ∟Hotel.java
 ∟HotelTest.java
Hotel.java
package test.dto;

import org.bson.types.ObjectId;

import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Id;

@Entity
public class Hotel {
	
	@Id
	private ObjectId id;
	private String name;
	private int starts;
	private Address address;
	
	
	public ObjectId getId() {
		return id;
	}
	public void setId(ObjectId id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getStarts() {
		return starts;
	}
	public void setStarts(int starts) {
		this.starts = starts;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
}
Address.java
package test.dto;

import com.google.code.morphia.annotations.Embedded;

@Embedded
public class Address {
	
	private String street;
	private String city;
	private String postCode;
	private String country;
	
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getPostCode() {
		return postCode;
	}
	public void setPostCode(String postCode) {
		this.postCode = postCode;
	}
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
}

上記2つのクラスを準備します。

Morphiaを使用してオブジェクトを保存する

データベース名をhotel_database
コレクション名をHotel
として、実際に保存してみます。

HotelTest.java
package test;

import test.dto.Address;
import test.dto.Hotel;

import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
import com.mongodb.Mongo;

public class HotelTest {
	
	public static void main(String[] args) throws Exception{
		
		//準備
		Mongo mongo = new Mongo("127.0.0.1", 27018);
		Morphia morphia = new Morphia();
		morphia.map(Hotel.class).map(Address.class);
		
		Datastore datastore = morphia.createDatastore(mongo, "hotel_database");
		
		Hotel hotel = new Hotel();
		hotel.setName("My Hotel");
		hotel.setStarts(4);
		
		Address address = new Address();
		address.setStreet("123 Some Street");
		address.setCity("Some Sity");
		address.setPostCode("123 4567");
		address.setCountry("Some Country");
		
		hotel.setAddress(address);
		
		datastore.save(hotel);		
	}	
}

HotelTestを実行すれば完了です。

データを取得してみます。

> db.Hotel.findOne()
{
        "_id" : ObjectId("4dfedf9950755d6dd2819102"),
        "className" : "test.dto.Hotel",
        "name" : "My Hotel",
        "starts" : 4,
        "address" : {
                "street" : "123 Some Street",
                "city" : "Some Sity",
                "postCode" : "123 4567",
                "country" : "Some Country"
        }
}


ドキュメントに含まれているクラス名やコレクション名の変更は、
@Entityアノテーションで設定できます。

@Entityアノテーション

@Entityアノテーションは、クラスをコレクション内にドキュメントとして永続化することを宣言します。

また、コレクションの名前の定義などの設定を行います。
Morphiaは、クラス名をコレクション名に設定します。

Entity.java
package com.google.code.morphia.annotations;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.TYPE})
public @interface Entity
{
  public abstract String value();

  public abstract CappedAt cap();

  public abstract boolean noClassnameStored();

  public abstract boolean slaveOk();

  public abstract String concern();
}
コレクション名を「hotels」にする場合
@Entity("hotels")
public class Hotel {
ドキュメントにクラス名を含めない場合
@Entity(noClassnameStored=true)
public class Hotel {