Play Framework + ReactiveMongo

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的环境搭建。

安装

首先你得安装Play!以及MongoDB
play!的安装不必多说,下载安装SBT,去Play官网下载Activator,添加环境变量,然后activator new一个工程就可以了。

创建好mosquito-mongo工程目录如下:

MongoDB的安装也很简单,去官网下载安装,然后添加环境变量就可以。不过需要注意,要自己指定数据存放位置。如,我将数据存放在D:\MongoDB\data中,只需要在d:\MongoDBdata文件夹就行:

然后就可以这样启动:

到这里,playmongodb就都已安装好了,接下来我们可以实现一个小的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自增)。

最后再查询全部。

Github源码

心尖依然偏左。
 

Play Framework + ReactiveMongo的更多相关文章

  1. Play Framework + ReactiveMongo 环境搭建

    Play!是一个full-stack(全栈的)Java/Scala Web应用框架,包括一个简单的无状态MVC模型,具有Hibernate的对象持续,一个基于Groovy的模板引擎,以及建立一个现代W ...

  2. windows类书的学习心得

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  3. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  4. Entity Framework Core 1.1 升级通告

    原文地址:https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/ 翻译:杨晓东 ...

  5. Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

    将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...

  6. 在传统.NET Framework 上运行ASP.NET Core项目

    新的项目我们想用ASP.NET Core来开发,但是苦于我们历史的遗产很多,比如<使用 JavaScriptService 在.NET Core 里实现DES加密算法>,我们要估计等到.N ...

  7. 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)

    前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...

  8. 来,给Entity Framework热热身

    先来看一下Entity Framework缓慢的初始化速度给我们更新程序带来的一种痛苦. 我们手动更新程序时通常的操作步骤如下: 1)把Web服务器从负载均衡中摘下来 2)更新程序 3)预热(发出一个 ...

  9. 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)

    前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这 ...

随机推荐

  1. 编辑简单的 shell程序

    编辑简单的 shell程序 知道了vi编辑器的使用规则之后,结合shell的使用规则,可以编辑简单的 shell程序试试手 题目如下: 1.用while语句创建一个根据输入的数值求累加和(1+2+3+ ...

  2. 第三方框架和ARC

    在使用了ARC机制的项目中使用第三方开源框架的方法: 1.在第三方开源框架的每个.m文件都设置成    -fno-objc-arc 具体方法:TARGETS--->Build Phases -- ...

  3. Visual Studio 有哪些好用的插件?

    推荐一批绝大部分都是免费的能较好增强写代码舒适度的. .NET Demon -- (非免费)安装后可以连续编译, 如果不买License的话过期后也还有代码改动后自动保存的上好功能, 安装它之后再也不 ...

  4. android于src和background差额

    ImageView中XML属性src和background的差别: background会依据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小.不会进行拉伸.src是图片内容(前 ...

  5. 检验身份证的正确性(C语言版本)

    /* check id_card * write by sndnvaps<sndnvaps@gmail.com> * ai -> a1 , a2, a3, a4, a5, a6... ...

  6. Visual Prolog 的 Web 专家系统 (7)

    GENI核心 -- 推理引擎(1)知识表示 GOAL最后一句是谓语infer(),它的含义是"论证". 因此,,进GENI核心,执行视图推理引擎. infer() infer(): ...

  7. JavaScript动漫作品(闭幕)

    笔者:Steven Riche 发布时间:2014年2一个月18 原文链接:http://code.tutsplus.com/tutorials/javascript-animation-that-w ...

  8. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  9. UML学习(一)类图和对象图

    对象是一个概念,一种抽象或者事物.对象能够是具有现实意义的事物,也能够是抽象的一个概念.比方,一家公司或者一个进程. 类是一组对象的集合或者抽象的概念.类具有同样的属性和方法. 介绍完基本对象和类的基 ...

  10. Linux Kernel(Android) 加密算法汇总(三)-应用程序调用内核加密算法接口

    于Linux Kernel(Android) 加密算法总结(cipher.compress.digest)文章中.介绍了怎样在内核中增加三种不同类型的内核加密算法, 并给出了在内核模块中怎样调用他们的 ...