Ale*_*nov 27 java orm scala sqlalchemy relational-database
作为一个不熟悉Python的人,我经常听到很多赞美SQLAlchemy.所以我想明白:
Java(或Scala)世界中是否有更接近的等价物?我见过Apache Empire-DB在这方面提到过......
Dha*_*ene 17
关于SQLAlchemy的一个值得注意的事情是它使表成为第一类对象.因此,核心API实际上是围绕表对象编写的,因此API本质上是关系性的.因此,在这个级别,即使API是OO,它本质上反映了RDBMS对象或函数,如表,列,关系,联接,别名等.在这个级别,SQLAlchemy为您提供了一个OOSQL,其中SQL和关系数据库没有给出二等治疗.此外,SQLAlchemy真的很闪耀,因为这种抽象级别使您能够降低到一点"原始"关系级别,从而获得巨大的灵活性,我真的没有看到任何其他ORM提供.有趣的是,在ORM中建模类继承所需的一些底层功能是在这一层实现的,例如.加入表继承http://docs.sqlalchemy.org/en/rel_0_7/orm/inheritance.html#joined-table-inheritance
更经常使用的API(至少最近)是声明性API,它实际上是更多的OO,并将业务域中的对象映射到我上面提到的对象(在大多数情况下是透明的).这是ORM功能的用武之地,API与其他ORM API有点类似,其中一个用于域对象,这些操作直接转换为基础表操作.
尽我的意识,在斯卡拉奥姆斯还在追赶到什么是Java(如继承)容易获得,即使他们提供其他功能(如类型安全,LINQ样结构),即使他们奋斗与一些严重的问题,如22列限制.(我读过评论,其中很少有人想知道为什么有人需要超过22列,至少根据我的经验,有些情况我不会称之为稀有,其中需要的是其中的倍数).
scala中的ORM(即使它们具有与Java不同的风格)我认为仍然可以追踪到所需的内容.关于SQLAlchemy,是否有足够接近我在Java或Scala中看到过的东西?我还没见过.
编辑:我忘记添加的一件事是,即使使用声明性API,SQLAlchemy仍然允许您直接访问底层对象.因此,如果"class Foo"以声明方式映射,则Foo .__ table__是您可以直接使用的表对象(如果您愿意).
Dav*_*ker 10
Squeryl提供了类似于他们在图书馆主页上的"SQLALCHEMY'S哲学"中所谈论的可组合性.您可以查询查询.
val query = from(table)(t => where(t.a === 1) select(t))
val composed = from(query)(q => where(q.b === 2) select(q))
Run Code Online (Sandbox Code Playgroud)
它也分享了设计理念的很大一部分,主要是当事情变得复杂时,图书馆应该"摆脱困境"并允许开发人员自己调整事物.虽然Squeryl做对象映射,但我认为它更像是一个DSL而不是一个ORM.
通过快速浏览SQLAlchemy功能列表,您无法分享的一些功能:
当然,Squeryl还提供了我认为Python库无法实现的主要功能,即编译器检查查询类型的安全性.
ScalaQuery(请参阅底部有关"光滑"的说明)可以做到这一点:
for{
a <- Article
if a.dateCreated between(start, end)
_ <- Query groupBy a.reporterID orderBy a.dateCreated.desc
} yield(a)
Run Code Online (Sandbox Code Playgroud)
或任意复杂的通过组成:
val team = for{
t <- Team
s <- School if t.schoolID is s.id
} yield (t,s)
val player = for{
r <- Roster
p <- Player if r.playerID is p.id
} yield (r, p)
val playerDetail = for{
(r, p) <- player
} yield (p.id, p.firstName, p.lastName, r.jerseyID, r.position, r.gamesPlayed)
val scoring = for{
(r, p) <- player
s <- Scoring if p.id is s.playerID
detail <- playerDetail
} yield (r, p, s, detail)
val scoringDetail = for{
(r, p, s, detail) <- scoring
val (total, goals, assists) =
(s.playerID.count, s.goal.sum, (s.assist1.sum + s.assist2.sum))
val ppg = (s.playerID.count / r.gamesPlayed)
} yield (goals, assists, total, ppg)
Run Code Online (Sandbox Code Playgroud)
以下是如何获得团队统计数据(可以修改联赛或单人球员视图):
val forScoring = for{
start ~ end ~ teamID <- Parameters[JodaTime,JodaTime,Int]
(r,p,s,player) <- scoring if r.teamID is teamID
comp <- bindDate(start, end) if s.gameID is comp.id
(goals, assists, total, ppg) <- scoringDetail
_ <- Query groupBy p.id orderBy ( ppg.desc, total.asc, goals.desc )
} yield (player, goals, assists, total, ppg)
def getScoring(start: JodaTime, end: JodaTime, id: Int): List[TeamScoring] = {
forScoring(start, end, id).list
}
Run Code Online (Sandbox Code Playgroud)
我不认为在Scala中生成强类型的复杂查询是可能的,并且已经让我自己只是移植了尝试过的真正的手写SQL; 也就是说,直到我遇到ScalaQuery,这是一个启示,就像Scala语言本身一样.
无论如何,你有选择,Squeryl可能更符合SQL Alchemy,不知道,探索一下,你可能不会失望,有很多Scala善良提供,很难不感到头晕目眩这里,现在和之后;-)
PS 大谈由Zeiger和沃格特在斯卡拉天技能事项SLICK,ScalaQuery的下一个演进
归档时间: |
|
查看次数: |
8294 次 |
最近记录: |