hangscer

Essential Slick 学习笔记(三) —— Creating and Modifying Data

2017/06/09

Inserting Rows

Inserting Single Rows

插入单行数据

1
2
val insertAction= messages += Message(1L,"jianghang2","asdsadsa2")
val r:Int=Await.result(db.run(insertAction),Inf)

Primary Key Allocation

主键分配策略:当插入数据数据时,我们需要告诉数据库自动分配主键,还是由用户分配主键。

Slick允许我们在声明模式列定义时,说明主键以及分配策略:

1
2
3
4
5
6
class MessageTable(tag: Tag)extends Table[Message](tag,"t_message"){
def id=column[Long]("id",O.PrimaryKey,O.AutoInc)
def sender=column[String]("sender")
def content=column[String]("conetnt")
def * = (id,sender,content).mapTo[Message]
}

O.AutoInc声明的列,在会被Slick在构建SQL语句时自动忽略,无论你是否指明特定值。

1
2
println(insertAction.statements.mkString)
// insert into `t_message` (`sender`,`conetnt`) values (?,?)

+=方法一定会在构建SQL语句时,把自增字段省略的。
那么该如何强制插入数据呢(包括用户指定的主键字段)?
解决方法就是forceInsert方法:

1
2
3
4
val insertAction= messages forceInsert Message(100L,"jianghang2","asdsadsa2")
val r:Int=Await.result(db.run(insertAction),Inf)
println(insertAction.statements.mkString)
//insert into `t_message` (`sender`,`conetnt`) values (?,?)

Retrieving Primary Keys on Insert

特别说明:mysql可以使用select last_insert_id()来获取自增id,LAST_INSERT_ID()基于Connection的,也就是说LAST_INSERT_ID()会返回该connection对列最新的insert 或者update操作生成的id值,该id值不受其他客户端(Connection)的影响。
但是Slick使用何种操作返回自增id,文档中并没有明确说明(也许是jdbc级别的支持)。

1
2
val insertAction = messages.returning(messages.map(_.id)) += Message(0L,"hang1","hahahahha1")
println(Await.result(db.run(insertAction),Inf))

Inserting Specific Columns

如果说列的部分字段已经有了默认值,那么在代码中就没有必要再次写明列值。

1
2
println(messages.map(_.content).insertStatement)
// insert into `t_message` (`conetnt`) values (?)

由此可以向+=传入String:

1
2
println((messages.map(_.content)+="conetc:hahahahaha").statements.mkString)
//insert into `t_message` (`conetnt`) values (?)

这句话会发生运行时错误,因为模式中的其他列为非空(non-nullable)。没关系,我们将会在以后讨论模式设计。

Inserting Multiple Rows

多行插入,批量插入
使用++=方法
略…

Deleting Rows

类似的,在Query对象上调用delete方法,返回deleteAction。

1
2
3
val query=messages.filter(_.id===2L)
val deleteAction=query.delete
Await.ready(db.run(deleteAction),Inf)

Updating Rows

Updating a Single Field

类似的,需要在Query中调用update方法,即可得到updateAction
更新单列值

1
2
println(messages.filter(_.sender === "jiang1").map(_.content).updateStatement.mkString)
//update `t_message` set `conetnt` = ? where `t_message`.`sender` = 'jiang1'
1
2
val updateAction=messages.filter(_.sender === "jiang1").map(_.content).update("hahahahahahah1")
Await.result(db.run(updateAction),Inf)

Updating Multiple Filed

更新多列值

1
2
val action=messages.filter(_.id===100L).map(m=>(m.sender,m.content)).update(("jianghang","hahahahahahahahah1"))
Await.result(db.run(action),Inf)

Updating with a Computed Value

在原有列值计算加工后再更新对应的列值,你可能会这样想:

1
update `t_message` set `cotent`=CONCAT(`conetnt,'!!!'`)

很遗憾,暂时Slick并不支持此功能。
可以直接使用SQL语句完成。