Play Framework + ReactiveMongo

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源码

时间: 2024-10-01 01:04:25

Play Framework + ReactiveMongo的相关文章

利用 Django REST framework 编写 RESTful API

利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framework 真乃一大神器,可以轻易的甚至自动化的搞定很多事情,比如: 自动生成符合 RESTful 规范的 API 支持 OPTION.HEAD.POST.GET.PATCH.PUT.DELETE 根据 Content-Type 来动态的返回数据类型(如 text.json) 生成 browserable

iOS库--.a与.framework

一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存. 三.iOS里静态库形式? .a和.framework 四.iOS里动态库形式? .dylib和.framework 五.framework为什么既是静态库又是动态库? 系统的.framework是动态库,我们自己建立的.fram

Multithreading Batch Processing Framework

1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # Author: f0rsaken 4 5 import argparse 6 import importlib 7 import sys 8 import threadpool 9 import time 10 11 def main(): 12 parser = argparse.ArgumentParser(description="Multithreading Batch Proce

安装mysql时,提示This application requires .NET framework 4.0问题

Question:双击MySQL的安装文件, 弹框提示, Answer:安装微软的 .NET Framework 4或更新的版本,下载地址:https://www.microsoft.com/zh-cn/Search/result.aspx?q=.net+framework&x=0&y=0 安装完成后安装MySQL即可.

使用自定义的framework

1.创建framework工程,创建需要的类将接口暴露在public中 2.运行后可在window/projects 的Derived Data中找到framwork所在路劲(分别在真机和模拟器下运行,会在product文件中生成不同的文件) 3.使用lipo命令合并库 lipo -create 库1的路径 库2的路劲 -ouput 库名 (图为库) 将生成的库(如果没有设置的话,库生成在根目录上),将其复制到模拟器或者真机的framework中覆盖原有的库. 4.在新工程中导入framewor

Entity Framework的查询

Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). 1.简单查询: SQL: SELECT * FROM [Clients] WHERE Type=1 AND Deleted=0 ORDER BY ID EF: //Func形式 var clients = ctx.Clients.Where(c => c.Type == 1 && c.D

Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Frist实现数据访问管理. 本例,我们模拟一个N层场景,用单独的客户端(控制台应用)来调用单独的基于REST服务的Web网站(WEB API应用) . 注意:每层使用单独的Visual Studio 解决方案, 这样更方便配置.调试和模拟一个N层应用. 假设有一个如Figure 9-3所示的旅行社和预订

Entity Framework 学习

Entity Framework 学习初级篇1--EF基本概况... 2 Entity Framework 学习初级篇2--ObjectContext.ObjectQuery.ObjectStateEntry.ObjectStateManager类的介绍... 7 Entity Framework 学习初级篇3-- LINQ TOEntities. 10 Entity Framework 学习初级篇4--EntitySQL. 17 Entity Framework 学习初级篇5--ObjectQ

原因是未找到“sgen.exe”,或未安装 .NET Framework SDK v2.0

visual studio编译出现错误:错误 2 任务失败,原因是未找到“sgen.exe”,或未安装 .NET Framework SDK v2.0.该任务正在注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework 的 SDKInstallRootv2.0 值中指定的位置下的“bin”子目录中查找“sgen.exe”.您可以通过执行下列操作之一,来解决这一问题: 1.) 安装 .NET Framework SDK v2.0.2.) 将上