我试图理解Slick如何工作以及如何使用它...并在GitHub中查看他们的示例我最终在MultiDBCakeExample.scala中使用了这段代码:
trait PictureComponent { this: Profile => //requires a Profile to be mixed in...
import profile.simple._ //...to be able import profile.simple._
object Pictures extends Table[(String, Option[Int])]("PICTURES") {
...
def * = url ~ id
val autoInc = url returning id into { case (url, id) => Picture(url, id) }
def insert(picture: Picture)(implicit session: Session): Picture = {
autoInc.insert(picture.url)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想该*方法在表中返回一行,同时autoInc应该以某种方式提供自动递增实体ID的功能......但说实话,我在理解这段代码时遇到了一些麻烦.什么returning指的是?什么autoInc回报?
我查看了Slick文档但我无法找到有用的信息.任何帮助将非常感激 ;-)
因为这autoInc可能会令人困惑,我将为您提供一个工作示例(请注意我的数据库是PostgreSQL,所以我需要进行黑客攻击forInsert才能使Postgresql驱动程序增加auto-inc值).
case class GeoLocation(id: Option[Int], latitude: Double, longitude: Double, altitude: Double)
/**
* Define table "geo_location".
*/
object GeoLocations extends RichTable[GeoLocation]("geo_location") {
def latitude = column[Double]("latitude")
def longitude = column[Double]("longitude")
def altitude = column[Double]("altitude")
def * = id.? ~ latitude ~ longitude ~ altitude <> (GeoLocation, GeoLocation.unapply _)
def forInsert = latitude ~ longitude ~ altitude <> ({ (lat, long, alt) => GeoLocation(None, lat, long, alt) },
{ g: GeoLocation => Some((g.latitude, g.longitude, g.altitude)) })
}
Run Code Online (Sandbox Code Playgroud)
我的RichTable是一个抽象类,为了不为每个表声明id,只是扩展它:
abstract class RichTable[T](name: String) extends Table[T](name) {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
val byId = createFinderBy(_.id)
}
Run Code Online (Sandbox Code Playgroud)
并使用它像:
GeoLocations.forInsert.insert(GeoLocation(None, 22.23, 25.36, 22.22))
Run Code Online (Sandbox Code Playgroud)
由于你传递None了id,当Slick插入这个新实体时,它将由PostgreSql驱动程序自动生成.自从我开始使用Slick之后的几个星期,我真的推荐它!
更新:如果你不想使用forInsert投影,另一种方法如下 - 在我的情况下实体是Address.
在架构创建时为每个表创建序列:
session.withTransaction {
DBSchema.tables.drop
DBSchema.tables.create
// Create schemas to generate ids too.
Q.updateNA("create sequence address_seq")
}
Run Code Online (Sandbox Code Playgroud)
定义一个使用序列生成id的方法(我once在RichTable课堂上定义了这个:
def getNextId(seqName: String) = Database { implicit db: Session =>
Some((Q[Int] + "select nextval('" + seqName + "_seq') ").first)
}
Run Code Online (Sandbox Code Playgroud)
并在映射器覆盖insert方法,如:
def insert(model : Address) = Database { implicit db: Session =>
*.insert(model.copy(id = getNextId(classOf[Address].getSimpleName())))
}
Run Code Online (Sandbox Code Playgroud)
现在,你可以None在插入时传递,这个方法将为你做一个很好的工作......
| 归档时间: |
|
| 查看次数: |
1819 次 |
| 最近记录: |