Play!是一個full-stack(全棧的)Java/Scala Web應用框架,包括一個簡單的無狀態MVC模型,具有Hibernate的對象持續,一個基於Groovy的模板引擎,以及建立一個現代Web應用所需的所有東西。
Mongo DB 是目前在IT行業非常流行的一種非關系型數據庫(NoSql),其靈活的數據存儲方式備受當前IT從業人員的青睞。Mongo DB很好的實現了面向對象的思想(OO思想),在Mongo DB中 每一條記錄都是一個Document對象。Mongo DB最大的優勢在於所有的數據持久操作都無需開發人員手動編寫SQL語句,直接調用方法就可以輕松的實現CRUD操作。
ReactiveMongo 是一個 MongoDB 的 Scala 驅動,提供完全的非堵塞和異步 I/O 操作。
以上就百度百科對Play! 以及MongoDB的簡介。這篇博客就是簡單的介紹Play+Mongo的環境搭建。
工具與環境:
- 編譯器 -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工程目錄如下:
MongoDB
的安裝也很簡單,去官網下載安裝,然后添加環境變量就可以。不過需要注意,要自己指定數據存放位置。如,我將數據存放在D:\MongoDB\data
中,只需要在d:\
下MongoDB
與data
文件夾就行:
然后就可以這樣啟動:
到這里,play
與mongodb
就都已安裝好了,接下來我們可以實現一個小的demo。
配置
添加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自增)。
最后再查詢全部。