2013-02-05 44 views
3

我即將在Lift框架中開始我的第一個項目,我必須決定選擇哪個持久性庫。我即將使用關係後端,因此Mapper和Record都可以投入使用。Mapper與Record/Squeryl

在Mapper的情況下 - 我最想念的事情是控制發送到RDBMS的查詢的能力 - 特別是當涉及更復雜的查詢時,可以通過SQL中的連接,聚合等來解決。看看下面的例子 - 讓我們有以下兩個實體:

class BaseProduct extends LongKeyedMapper[BaseProduct] with IdPK { 
    // some fields 
} 
object BaseProduct extends BaseProduct with LongKeyedMetaMapper[BaseProduct] 

class MyProduct extends LongKeyedMapper[MyProduct] with IdPK { 
    // some fields 
    object base extends MappedLongForeignKey(this, BaseProduct) 
} 
object MyProduct extends MyProduct with LongKeyedMetaMapper[MyProduct] 

哪裏MyProductBaseProduct實體一體的專業化。顯然這些實體之間有一對一的關係。不過,我已經拿出最好的可能性的確切MyProduct查詢其BaseProduct在一起就好像這樣的查詢:

MyProduct.findAll(PreCache(MyProduct.base)) 

哪些問題兩個查詢(而且我怕我不能夠控制哪些領域我想要選擇的MyProduct實體

對Mapper庫來說足夠糟糕我對Record/Squeryl API的主要擔憂是它缺少Mapper API附近的所有Proto類。一些與Record的這些類的功能接近的東西?是否可以訪問Squeryl中的數據庫特定功能(例如幾何PostgreSQL中的查詢)?

這些圖層中是否有其他優點和缺點?還是有任何其他的抽象層,如果我想與數據庫有良好的類型安全封裝的通信封裝,並提供對查詢的體面控制(我曾被用來直接使用PHP中的PDO層發佈查詢 - 不想要這樣的直接查詢接口,但有一些控制查詢的可能性會很大)與Lift框架的集成絕對是一個優勢。

謝謝!

回答

5

我們一直在使用Squeryl和Lift很長一段時間,並對此非常滿意。根據您以上的情況下,在Squeryl的當前版本的版本(0.9.5),你可以這樣做:

class BaseProduct(id:Long, some more fields) extends KeyedEntity[Long] { 

} 

class MyProduct(id:Long, some more fields) extends KeyedEntity[Long] { 

} 

然後,你就必須定義relationships像模式(我假設他們是加入了對ID字段):

val baseProducts = Table[BaseProduct]("base_products") 
val myProducts = Table[MyProduct]("my_products") 
val myProductsToBaseProducts = 
    oneToManyRelation(myProducts, baseProducts).via((mp, bp) => 
    mp.id === bp.id) 

要查詢兩個記錄,你會做這樣的事情:

from(myProducts, baseProducts) ((mp, bp) => 
    where(mp.id === bp.id and mp.id === LOOKUPVAL) 
    select(bp, mp)) 

上面的查詢將返回從(BaseProduct,MarketProduct)的元組一個SQL選擇。

您還可以使用的關係來獲取相關項目,如通過添加這種方法MyProduct

def baseProduct = myProductsToBaseProducts.left(this) 

然而,就像從映射你的榜樣,它會發出第二個查詢。至於進行數據庫特定查詢,有&運算符,它允許您在服務器上評估表達式。如果該功能在Squeryl中不可用,您可以創建custom functions。總之,我發現Squeryl非常靈活,並且是ORM和直接SQL之間的一個很好的混合體。它的表現非常好,我沒有發現太多Squeryl禁止我輕鬆獲取所需數據庫功能的地方。在下一個版本中它變得更加容易,因爲0.9.6在custom types上具有更大的靈活性。

+0

謝謝! Squeryl對我來說似乎是一個很好的選擇......還有一個問題 - 我認爲沒有開箱即用的支持(如Mapper框架中的Proto類所提供的)不適用於Record/Squeryl。或者你知道一些具有類似功能的庫嗎? (或者我必須將Squeryl和Mapper集成到一個項目中,如果我需要這個功能而不需要自己動手的話) –

+0

Squeryl/Record目前沒有現成的實現。我的理解是,沒有唯一的原因是由於ProtoUser中的id和定義主鍵的Squeryl的KeyedEntity中的id有衝突。使用0.9.6時,這應該很容易解決,並且在發佈時可能會被修復。同時,我可能會做的只是複製ProtoUser的代碼並修改您自己的版本以解決衝突。 – jcern