编写 Slick 3.0 查询时最小化 Boiler Plate 代码
Minimize Boiler Plate code when writing Slick 3.0 Queries
我在 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)
我想知道是否有一种通用且安全的方法来避免在每个函数中重复使用这些行。
您可以定义一个通用函数,例如
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)
}
我在 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)
我想知道是否有一种通用且安全的方法来避免在每个函数中重复使用这些行。
您可以定义一个通用函数,例如
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)
}