我在slick 3.0中编写了我的第一个数据访问对象。它有效,但我在代码中发现了很多重复的代码
class Items(tag: Tag) extends Table[Item](tag, "ITEMS") {
def id = column[Long]("ITEMS_ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("ITEMS_NAME")
def price = column[Double]("ITEMS_PRICE")
def * = (id, name, price) <> ((Item.apply _).tupled, Item.unapply _)
}
object Shop extends Shop{
val items = TableQuery[Items]
val db = Database.forConfig("h2mem1")
def create(name: String, price: Double) : Int = {
val action = items ++= Seq(Item(0, name, price))
val future1 = db.run(action)
val future2 = future1 map {result =>
result map {x => x}
}
Await.result(future2, Duration.Inf).getOrElse(0)
}
def list() : Seq[Item] = {
val action = items.result
val future = db.run(action)
val future2 = future map {result =>
result map {x => x}
}
Await.result(future2, Duration.Inf)
}
def get(id: Long) : Option[Item] = {
val query = items.filter(_.id === id).result
val future1 = db.run(query)
val future2 = future1 map {result =>
result.map {x => x}
}
Await.result(future2, Duration.Inf).headOption
}
def delete(id: Long) : Int = {
val query = items.filter(_.id === id).delete
val future1 = db.run(query)
val future2 = future1 map {result =>
result
}
Await.result(future2, Duration.Inf)
}
def update(item: Item) : Int = {
val query = items.filter(_.id === item.id).update(item)
val future1 = db.run(query)
val future2 = future1 map {result => result}
Await.result(future2, Duration.Inf)
}
def createItemsTable() : Boolean = {
if (!checkTable("ITEMS")) {
val action = items.schema.create
val future1 = db.run(action)
future1 map {x => x}
true
} else false
//Await.result(future2, Duration.Inf)
}
def checkTable(tableName: String) : Boolean = {
val action = MTable.getTables
val future1 = db.run(action)
val future2 = future1 map {result =>
result map {x => x.name.name}
}
val retVal = Await.result(future2, Duration.Inf)
retVal.exists(x => x == tableName)
}
}
这有效,但我讨厌我一次又一次地编写这段代码的事实
val future1 = db.run(query)
val future2 = future1 map {result => result}
Await.result(future2, Duration.Inf)
和
val future1 = db.run(query)
val future2 = future1 map {result =>
result.map {x => x}
}
Await.result(future2, Duration.Inf)
我想知道是否有一种通用且安全的方法可以避免在每个函数中重复使用这些行。
答案 0 :(得分:2)
您可以定义类似
的通用函数def runAction[R, Q](action: DBIOAction[R, NoStream, Nothing])(f: R => Q): Q = {
val future1 = db.run(action)
val future2 = future1 map { r: R =>
f(r)
}
Await.result(future2, Duration.Inf)
}
并像
一样使用它def create(name: String, price: Double): Int = {
val action = items ++= Seq(Item(0, name, price))
runAction(action)(_.map(x => x)).getOrElse(0)
}