`

【playframework2笔记整理】2、数据持久化操作

 
阅读更多

本文来自:fair-jm.iteye.com 转截请注明出处

 

许久没有更新了 最近比较忙

要考试

自己也在写点其他的东西 仿照it客的视频写一个模仿拉手网安卓客户端的app

 

有兴趣的可以关注下:

https://github.com/fairjm/mylashou

https://github.com/fairjm/mylashou_server

其中server我打算用play改写视频中使用的servlet 

 

好 废话不多说 第二篇的笔记整理 主要讲数据持久化  利用play自带的anorm(默认就有的) 

slick 我的博客文章有介绍(http://fair-jm.iteye.com/blog/2070127)

squeryl 我用的不熟练 笔记中也没记录使用

 

在play console下要测试model的话可以使用

new play.core.StaticApplication(new java.io.File("."))

然后就可以像平常使用console一样操作那些model了

 

evolution:

这是一种自动更新表结构的功能 具体使用的话:

可以在conf/evolutions/default 写sql 用数字1开始命名
格式:

 

# --- !Ups      这个是执行升级的语句开始
写建立的语句
# --- !Downs    执行降级的语句开始
写删除的语句

 

 

使用Anorm:
 用anorm.SQL来执行sql

查询:

val sql: SqlQuery = SQL("select * from products order by name asc")

 

获取结果三种方式:

1、第一种直接执行Row的apply方法 第二种用模式匹配 第三种用解析器组合:
sql执行有个隐函数(connection) 通过DB.withConnection得到:

import play.api.Play.current //import play.api.Play.current一定要导入 不然的话DB的隐含app函数会得不到
import play.api.db.DB
def getAll: List[Product] = DB.withConnection {
 implicit connection =>
  sql().map ( row =>
   Product(row[Long]("id"), row[Long]("ean"),
   row[String]("name"), row[String]("description"))
  ).toList
}  

sql()返回的是Stream[SqlRow] 所以最后要转成List

 

2、第二种用模式匹配:

def getAllWithPatterns: List[Product] = DB.withConnection {
implicit connection =>
 import anorm.Row
 sql().collect { //因为直接用了case所以用collect来执行接受一个偏函数
  case Row(Some(id: Long), Some(ean: Long),
   Some(name: String), Some(description: String)) =>
   Product(id, ean, name, description)
 }.toList
}

 

 

3、第三种用转换器:

 

RowParser[Product] -> ResultSetParser[List[Product]] -> 用sql的as函数:
import anorm.RowParser
val productParser: RowParser[Product] = {
 import anorm.~
 import anorm.SqlParser._
 long("id") ~                 
 long("ean") ~
 str("name") ~
 str("description") map {
  case id ~ ean ~ name ~ description =>
  Product(id, ean, name, description)
 }
}

得到RowParser执行 *得到ResultSetParser

def getAllWithParser: List[Product] = DB.withConnection {
 implicit connection =>
  sql.as(productParser *)
}

多个parser也可以用~连接 其实他就是做了获取结果之后一一对应然后赋值 用~操作符执行

 


增删改:
用SqlQuery的executeUpdate()方法

def insert(product: Product): Boolean =
DB.withConnection { implicit connection =>
val addedRows = SQL("""insert into products values ({id}, {ean}, {name}, {description})""").on(
    "id" -> product.id,"ean" -> product.ean,"name" -> product.name,"description" -> product.description
    ).executeUpdate()
 addedRows == 1 //返回的是修改的行
}
def update(product: Product): Boolean =
 DB.withConnection { implicit connection =>
 val updatedRows = SQL("""update products
  set name = {name},
  ean = {ean},
  description = {description}
  where id = {id}
  """).on(
   "id" -> product.id,
   "name" -> product.name,
   "ean" -> product.ean,
   "description" -> product.description).
  executeUpdate()
  updatedRows == 1
}
def delete(product: Product): Boolean =
 DB.withConnection { implicit connection =>
  val updatedRows = SQL("delete from products where id = {id}").
  on("id" -> product.id).executeUpdate()
  updatedRows == 0  //这边有误 如果删除了还是返回1
}

 

==============================================================

 

缓存(初步):


用系统自带的Cache
用set设置 用getAs获得 得到的是Some()或者None:

def show(productId: Long) {
 Cache.getAs[Product]("product-" + productId) match {
  case Some(product) => Ok(product)
  case None => Ok(Product.findById(productId))
 }
}

 

 

==============================================================
==============================================================

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics