使用Play Framework(v2.2.3)连接MongoDB

记录Play初学者学习并掌握MongoDB的过程。

环境

Mac OS X – 版本10.9.2
播放(java) – 版本2.2.3
MongoDB – 版本2.6.1
Eclipse – 版本4.3.2

源代码

吗啡

Morphia是一个轻量级的类型安全库,用于将Java对象与MongoDB进行映射。

玩嗨了

http://www.playframework.com/modules/morphia 上似乎有一个官方般的模块可以将Morphia集成到Play中。然而,由于它只能在1.x版本的Play中使用,所以无法使用。

玩游戏MongoDemo

我在公式文档中感觉到MongoDB相关的文档并不多,所以我随意搜索了一下,然后找到了一个使用play和morphia的演示项目,我克隆了它并试图使用play运行,但是出现了各种错误,无法运行。

看起来问题是因为play本身的版本不同造成的。

当我搜索”play migration”时,出现了很多关于版本迁移的页面,我按照这些步骤进行了尝试,但是并没有成功,所以我放弃了。

看起来在2.0、2.1、2.2版本之间有很大的差异啊。我希望有一个play版本管理工具,但是似乎并不存在吧?

玩新的我的应用

参考playMongoDemo的同时,我决定自己摸索着去做。

全球.java

將playMongoDemo中的東西完全複製。
根據GlobalSettings對象,在應用程序啟動時,似乎已經連接到MongoDB。
GlobalSettings
– http://www.playframework-ja.org/documentation/2.0.8/JavaGlobal

import java.net.UnknownHostException;

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

import controllers.MorphiaObject;
import play.GlobalSettings;
import play.Logger;

public class Global extends GlobalSettings {
  @Override
  public void onStart(play.Application arg0) {
    super.beforeStart(arg0);
    Logger.debug("** onStart **"); 
    try {
      MorphiaObject.mongo = new Mongo("127.0.0.1", 27017);
    } catch (UnknownHostException e) {
      e.printStackTrace();
    }
    MorphiaObject.morphia = new Morphia();
    MorphiaObject.datastore = MorphiaObject.morphia.createDatastore(MorphiaObject.mongo, "test");
    MorphiaObject.datastore.ensureIndexes();   
    MorphiaObject.datastore.ensureCaps();  

    Logger.debug("** Morphia datastore: " + MorphiaObject.datastore.getDB());
  }
}

由于Global.java中使用了MorphiaObject,在playMongoDemo中也定义了如下的副本。

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

public class MorphiaObject {
  static public Mongo mongo;
  static public Morphia morphia;
  static public Datastore datastore;
}

构建.sbt

为了使用在import语句中使用的”com.google.code.morphia”和”com.mongodb.Mongo”等库,需要在build.sbt文件中添加相应的配置。

libraryDependencies ++= Seq(
  javaJdbc,
  javaEbean,
  cache,
  "com.google.code.morphia" % "morphia" % "0.99",
  "org.mongodb" % "mongo-java-driver" % "2.7.3",
  "de.flapdoodle.embed" % "de.flapdoodle.embed.mongo" % "1.36" % "test"
)

我将在`libraryDependencies`中添加以下内容。默认情况下,只有`javaJdbc`,`javaEbean`和`cache`被写入,但是我将添加以下3个。最后一个将在编写测试时使用。
然后,为了使添加的库在`.classpath`等文件中生效,我将进入play控制台执行`eclipse with-source=true`等操作。如果无法正常执行,我会尝试执行`play clean`,然后再次尝试,目前为止一切顺利。

模特儿 (Mó tè ér)

https://github.com/brly/play-morphia-sample/blob/master/app/models/TestModel.java参照,按照playMongoDemo定义。在这个源示例中,缩减了成员数量,并进行了- ?

{
  name: String,
  value: Int
}

就是这种简单的样子。
并且,如果看源代码的话你就会明白,还可以使用Required注释之类的。

控制器和路由。

https://github.com/brly/play-morphia-sample/blob/master/conf/routes 即将变更为playMongoDemo的路由配置文件,请调整play.data.Form相关规范。

https://github.com/brly/play-morphia-sample/blob/master/app/controllers/Application.java 即将变更为playMongoDemo的Application控制器,请调整。由于play.data.Form的规范已经发生了变化,需要进行相应的调整。

观点/comment

我记得play-mongo-demo中的这个页面可以保持不变。

执行

スクリーンショット 2014-05-18 18.39.58.png

考试

テストを書かないと色々言われるご時世なので書かないといけませんが、環境を整えなければなりません。
MySQLの場合だとplayのfakeApplicationとかinMemoryDatabaseを使えば良かったのですが、それは使えないので用意する必要があります。

という訳でまたぐぐったところ、以下の記事を見つけます。
http://www.cubeia.com/2012/03/using-mongodb-for-your-game-data/
見慣れたMorphiaという単語が安心感を与えてくれますが、新たな”EmbedMongo”という単語が出てきます。

嵌入式Mongo

というわけで”embedded mongo unit test”とかで検索するといかにもなページがあります。
http://quillbytes.com/display/JAVA/Setting+Up+An+Embedded+MongoDB+Database+for+Unit+Tests
でサンプル例があるのですが、サンプルのテストが書きたい感じとちょっと違います。
例ではDBCollectionとかいうオブジェクトを使ってread/writeをしてます。
TestModel.javaではそんな感じに書いてなかったので、どうしたら良いのかよくわかりませんでしたがとりあえず以下のようにしたらfakeぽく動作するようになりました。

@Before
  public void beforeTest() {
    MorphiaObject.mongo = getMongoClient();
    MorphiaObject.datastore = new Morphia().createDatastore(getMongoClient(), "test");
  }

在每次使用@Before之前,我会编写测试代码来初始化并操作MorphiaObject类的mongo和datastore属性,以达到想要的测试效果。

 @Test
  public void 初期値は空リスト() {
    assertThat(TestModel.all()).isEmpty();
  }

  @Test
  public void addしたものが順番に取り出せる() {
    TestModel ts0 = new TestModel();
    ts0.name = "ほとココア";
    ts0.value = 15;
    TestModel.create(ts0);

    TestModel ts1 = new TestModel();
    ts1.name = "かふうチノ";
    ts1.value = 13;
    TestModel.create(ts1);

    TestModel ts2 = new TestModel();
    ts2.name = "てでざリゼ";
    ts2.value = 16;
    TestModel.create(ts2);

    TestModel ts3 = new TestModel();
    ts3.name = "うじまつチヤ";
    ts3.value = 15;
    TestModel.create(ts3);

    TestModel ts4 = new TestModel();
    ts4.name = "きりまシャロ";
    ts4.value = 15;
    TestModel.create(ts4);

    assertThat(TestModel.all()).hasSize(5);
    assertThat(TestModel.all().get(0).name).isEqualTo("ほとココア");
    assertThat(TestModel.all().get(1).name).isEqualTo("かふうチノ");
    assertThat(TestModel.all().get(2).name).isEqualTo("てでざリゼ");
    assertThat(TestModel.all().get(3).name).isEqualTo("うじまつチヤ");
    assertThat(TestModel.all().get(4).name).isEqualTo("きりまシャロ");
  }

所以,总算是搭建好了环境。

广告
将在 10 秒后关闭
bannerAds