作为一个不熟悉Python的人,我经常听到SQLAlchemy的好评。因此,我想了解:
在Java(或Scala)世界中,有更接近它的等价物吗?我曾看到Apache Empire-DB在这方面被提到...
作为一个不熟悉Python的人,我经常听到SQLAlchemy的好评。因此,我想了解:
在Java(或Scala)世界中,有更接近它的等价物吗?我曾看到Apache Empire-DB在这方面被提到...
最常用的API(至少最近)是声明式API,它实际上更加面向对象,并将业务域中的对象映射到上述对象中(在大多数情况下透明)。这就是ORM功能发挥作用的地方,API与其他ORM API有些类似,其中一个使用领域对象进行操作,这些操作直接转换为底层表操作。
据我所知,Scala中的ORM仍在努力追赶Java中容易获得的内容(例如继承),即使它们提供了其他功能(例如类型安全性、类似于LINQ的结构),即使它们在一些严重问题(例如22列限制)上存在问题。 (我读过一些评论,少数人想知道为什么有人需要超过22列,至少根据我的经验,有时需要多个列的情况并不罕见)。
我认为Scala中的ORM(即使它们呈现出不同的风格)仍在追赶所需内容。关于SQLAlchemy,在Java或Scala中是否有足够接近的等价物? 我没有看到过任何。
编辑:我忘记补充的一件事是,即使使用声明式API,SQLAlchemy仍然可以直接访问底层对象。因此,如果“class Foo”被映射为声明式,Foo.__table__就是表对象,如果需要,您可以直接使用它。
Squeryl 提供了类似于 "SQLALCHEMY'S PHILOSOPHY" 中所述的可组合性。您可以查询一个查询。
val query = from(table)(t => where(t.a === 1) select(t))
val composed = from(query)(q => where(q.b === 2) select(q))
ScalaQuery(请注意底部有关“slick”的注释)可以执行简单的操作:
for{
a <- Article
if a.dateCreated between(start, end)
_ <- Query groupBy a.reporterID orderBy a.dateCreated.desc
} yield(a)
或通过组合实现任意复杂性:
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)
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
}
我以前认为在Scala中生成强类型的复杂查询是不可能的,所以只能使用手写的SQL语句;直到我找到了ScalaQuery,这是一个启示,就像Scala语言本身一样。
无论如何,你有选择,Squeryl可能更符合SQL Alchemy,不确定,探索一下,你可能不会失望,在这里提供了很多Scala好东西,现在和未来都难免感到兴奋 ;-)
p.s. Zeiger和Vogt在Scala Days Skills Matters上的精彩演讲,介绍了SLICK,ScalaQuery的下一个进化版本
这是一个Java实现的“Active Record”设计模式。它的灵感来自于Ruby on Rails中的ActiveRecord ORM。它可能适合你的需求。
https://javalite.io/activejdbc
或者
这是一个Java的SQL便捷库。它试图使用集合、bean等符合Java语法的方式暴露关系数据库的访问,同时保持与JDBC相同的细节水平。