Play Framework + ReactiveMongo 環境搭建

Play!是一個full-stack(全棧的)Java/Scala Web應用框架,包括一個簡單的無狀態MVC模型,具備Hibernate的對象持續,一個基於Groovy的模板引擎,以及創建一個現代Web應用所需的全部東西。html

Mongo DB 是目前在IT行業很是流行的一種非關係型數據庫(NoSql),其靈活的數據存儲方式備受當前IT從業人員的青睞。Mongo DB很好的實現了面向對象的思想(OO思想),在Mongo DB中 每一條記錄都是一個Document對象。Mongo DB最大的優點在於全部的數據持久操做都無需開發人員手動編寫SQL語句,直接調用方法就能夠輕鬆的實現CRUD操做。react

ReactiveMongo 是一個 MongoDB 的 Scala 驅動,提供徹底的非堵塞和異步 I/O 操做。git

以上就百度百科對Play! 以及MongoDB的簡介。這篇博客就是簡單的介紹Play+Mongo的環境搭建。github

工具與環境:mongodb

  • 編譯器 -IDEA
  • Scala -version 2.11.6
  • Play -version 2.3.10
  • MongoDB -version 3.0.6
  • Sbt -version 0.13.8
  • Reactivemongo -version 0.10.5.0.akka23

安裝

首先你得安裝Play!以及MongoDB
play!的安裝沒必要多說,下載安裝SBT,去Play官網下載Activator,添加環境變量,而後activator new一個工程就能夠了。數據庫

建立好mosquito-mongo工程目錄以下:json

MongoDB的安裝也很簡單,去官網下載安裝,而後添加環境變量就能夠。不過須要注意,要本身指定數據存放位置。如,我將數據存放在D:\MongoDB\data中,只須要在d:\MongoDBdata文件夾就行:api

而後就能夠這樣啓動:mvc

到這裏,playmongodb就都已安裝好了,接下來咱們能夠實現一個小的demo。app

配置

添加play.plugins插件。在項目根目錄下的conf/文件夾下,建立play.plugins插件並加入

1100:play.modules.reactivemongo.ReactiveMongoPlugin

添加reactivemongo依賴。打開項目根目錄下build.sbt,添加:

"org.reactivemongo" %% "play2-reactivemongo" % "0.10.5.0.akka23"

配置鏈接。打開項目根目錄下的conf/文件夾下application.conf,加入:

# ReactiveMongo

mongodb.uri = "mongodb://localhost:27017/mosquito"

mongo-async-driver {
  akka {
loglevel = DEBUG
  }
}

創建全局的Global來獲取connection。在app目錄下建立Global.scala文件,並添加:

package global

object Global extends GlobalSettings {

    def db = ReactiveMongoPlugin.db
    def collection = db.collection[JSONCollection]("user")

    override def onStart(app: Application) {
        Logger.info("Application has started")
    }

    override def onStop(app: Application) {
        Logger.info("Application shutdown...")
    }
}

而後還須要在conf/文件夾下application.conf,加入:

application.global=global.Global

到此,全部配置都已結束,接下來實現業務邏輯了。

實現

創建模型。根目錄下創建models文件夾(若是沒有的話),並創建User.scala,並加入:

package models

import play.api.libs.json.Json

case class User(
                   var id:Option[Long],
                   var name:Option[String],
                   var password:Option[String],
                   var address :Option[String] = None)


trait JSONFormats {

    implicit val UserFormats = Json.format[User]

}

實現。在controllers/下的Application.scala中加入如下代碼:

package controllers

import akka.util.Timeout
import global.Global
import models.{JSONFormats, User}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json._
import play.api.mvc._

import scala.concurrent.Await
import scala.concurrent.duration._

// Reactive Mongo plugin, including the JSON-specialized collection
import play.modules.reactivemongo.MongoController

object Application extends Controller with MongoController with JSONFormats {

    implicit val timeout = Timeout(10 seconds)

    def index = Action {
        Ok(views.html.index("Your new application is ready."))
    }

    def add = Action { request =>
        request.body.asJson.get.validate[User] match {
            case s:JsSuccess[User] =>{
                val user = s.get
                Global.collection.insert(user)
                Ok(Json.obj("code" -> 200, "message" -> Json.toJson(user)))
            }
            case e:JsError => {
                InternalServerError(Json.obj("code" -> 500, "message" -> e.toString))
            }
        }
    }

    def query = Action.async {

        val userList = Global.collection.find(Json.obj())
            .cursor[User].collect[List](upTo = 100, stopOnError = true)

        userList.map(
            list => Ok(Json.obj("code" -> 200, "message" -> Json.toJson(list))))recover {
            case e : Exception => InternalServerError(Json.obj("code" -> 500, "message" -> JsNull))
        }

    }

    def retrieve(id:Int) = Action.async {

        val userOpt = Global.collection.find(Json.obj("id" -> id)).cursor[User].headOption

        userOpt.map(
            user => Ok(Json.obj("code" -> 200, "message" -> Json.toJson(user)))) recover {
            case e : Exception => InternalServerError(Json.obj("code" -> 500, "message" -> JsNull))
        }

    }

    def test = Action.async { request =>
        val reqJson = request.body.asJson.get

        val name = (reqJson \"name").asOpt[String]
        val password = (reqJson \"name").asOpt[String]
        val address = (reqJson \"address").asOpt[String]
        val idOpt = getId

        val user = User(
            idOpt,
            name,
            password,
            address
        )

        Global.collection.insert(user).map(
            u => Ok(Json.obj("code" -> 200, "message" -> Json.toJson(user))))recover {
            case e : Exception => InternalServerError(Json.obj("code" -> 500, "message" -> "Oops"))
        }

    }

    def getId:Option[Long] = {
        var ret = None:Option[Long]
        val userList = Global.collection.find(Json.obj())
            .cursor[User].collect[List](upTo = 100, stopOnError = true)

        val lastUserOpt = Await.result(userList, timeout.duration).lastOption

        if(lastUserOpt.isDefined){
            val id = lastUserOpt.get.id.get + 1
            ret= Option(id)
        }

        ret
    }

}

說明。

  • add 新增
  • query 查詢全部
  • retrieve 查詢單個(根據id查詢)
  • test 測試uid自增插入
  • getId 獲取最大uid傳遞給test(很low的方式,經過查詢出最大的id再+1賦值)

配置路由。在conf/文件夾下的routes中加入對應的路由:

GET        /user/:id            controllers.Application.retrieve(id:Int)
PUT        /user                controllers.Application.add
GET        /query               controllers.Application.query
PUT        /test                controllers.Application.test

總目錄結構以下:

測試

最後是跑一下。運行起來後直接自動建庫、建表。

運行成功。

測試一下查詢。

測試一下新增(id自增)。

最後再查詢所有。

Github源碼

相關文章
相關標籤/搜索