slick - 条件插入

书上给了例子,插入前可以根据条件来选择是否插入这个数据,但书上用的是 String常量,不能直接拿来实际用.

  1. 好处就是一条sql
  2. 不好的么,就是有点麻烦

两次查询完成插入

//  solution with twice query

def exists(item: Item) = orders.filter(order => order.id === item.id).result.headOption.flatMap {
case Some(item) => DBIO.successful(0)
// throw new Exception("test exception")
case _ => orders += item

一次查询

// solution with once query
def isExist(item: (ConstColumn[String], ConstColumn[Long])) = orders.filter(order => order.id === item._2).exists
val filterData = Query((item.name, item.id)).filterNot(isExist(_))

val query = orders.map(m => m.name -> m.id).forceInsertQuery(filterData)
println(query.statements)
db.run(query.asTry)

这里稍作解释:

  • Query((item.name, item.id)) 是实例一个Query类型 带着变量参数,目的是能够和后面filter 操作链接上

如果isExist判断是true的话,说明是这条记录存在,所以Query里的数据就被过滤了,不会被插入

  • 书上用的是forceInsert,但实际中发现forceInsert的参数是value类型的,也就是 (name,id) 这种tuple的形式,而后面形成的Query类型的数据.所以选择了forceInsertQuery

insert into “ORDERS” (“NAME”,”ID”) select ‘mac book’, 10022233222 where not exists(select “NAME”, “ID” from “ORDERS” where “ID” = 10022233222)