LINQ和Java
LINQ已經非常成功,但在.NET生態系統中也引起了爭議。 許多人正在Java世界中尋找可比的解決方案。 為了更好地理解什么是可比的解決方案,讓我們看一下LINQ解決的主要問題:
查詢語言通常是具有許多關鍵字的聲明性編程語言。 它們提供的控制流元素很少,但是具有很高的描述性。 最受歡迎的查詢語言是SQL ,這是ISO / IEC標準化的結構化查詢語言,主要用于關系數據庫。
聲明式編程意味著程序員不會明確聲明其算法。 相反,他們描述了他們想要獲得的結果,從而將算法計算留給了其實施系統。 一些數據庫已經非常善于解釋大型SQL語句,并基于語言語法和元數據應用了SQL語言轉換規則。 有趣的一讀是湯姆·凱特 ( Tom Kyte)的元數據問題 ,暗示了甲骨文基于成本的優化工具所付出的巨大努力。 對于SQL Server,DB2和其他領先的RDBMS,可以找到類似的論文。
LINQ-to-SQL不是SQL
LINQ是一種完全不同的查詢語言,它允許將聲明性編程方面嵌入到.NET語言(例如C#或ASP)中。 LINQ的一個優點是,C#編譯器可以在C#語句中間編譯類似于SQL的內容。 從某種意義上說,LINQ對.NET而言,SQL對PL / SQL,pgplsql或對Java的jOOQ而言 ( 請參閱我之前有關PL / Java的文章 )。 但是與嵌入實際SQL語言的PL / SQL不同, LINQ-to-SQL并非旨在在.NET中對SQL本身進行建模。 它是更高級別的抽象,為嘗試統一使用一種語言對各種異構數據存儲進行統一查詢提供了方便。 這種統一將產生與ORM相似的阻抗失配 ,甚至可能更大。 盡管相似的語言可以在某種程度上相互轉換,但是對于高級SQL開發人員而言,預測甚至是非常簡單的LINQ語句將生成什么實際的SQL代碼也變得非常困難。
LINQ示例
當查看LINQ-to-SQL文檔給出的一些示例時,這一點變得更加清楚。 例如Count()聚合函數:
System.Int32 notDiscontinuedCount =(from prod in db.Productswhere !prod.Discontinuedselect prod).Count();Console.WriteLine(notDiscontinuedCount);在上面的示例中,尚不清楚立即將.Count()函數轉換為帶括號的查詢中的SQL count(*)聚合函數(然后為什么不將其放入投影中?),或者是否將其應用僅在執行查詢后,才在應用程序內存中。 如果需要將大量記錄從數據庫傳輸到內存,則后者將是禁止的。 根據交易模型的不同,它們甚至需要被讀取鎖定!
此處給出了另一個示例,其中解釋了分組 :
var prodCountQuery =from prod in db.Productsgroup prod by prod.CategoryID into groupingwhere grouping.Count() >= 10select new{grouping.Key,ProductCount = grouping.Count()};在這種情況下,LINQ對它的語言方面建模完全不同于SQL。 上面的LINQ where子句顯然是SQL HAVING子句。 into grouping是將元組into grouping的別名,這是一個很好的主意。 但是,它不會直接映射到SQL,并且LINQ必須在內部使用它來生成類型化的輸出。 當然,很棒的是靜態類型的投影,之后可以直接在C#中重用!
讓我們看另一個分組示例:
var priceQuery =from prod in db.Productsgroup prod by prod.CategoryID into groupingselect new{grouping.Key,TotalPrice = grouping.Sum(p => p.UnitPrice)};在此示例中,C#的功能方面嵌入到LINQ的Sum(p => p.UnitPrice)聚合表達式中。 TotalPrice = ...只是簡單的列別名。 以上讓我有很多未解決的問題。 在SQL查詢返回部分結果集之后,如何控制哪些部分將真正轉換為SQL,以及哪些部分將在我的應用程序中執行? 我如何預測lambda表達式是否適合LINQ聚合函數,以及何時將導致將大量數據加載到內存中以進行內存聚合? 并且:編譯器會警告我,它無法弄清楚如何生成C#/ SQL算法組合嗎? 還是這只會在運行時失敗?
去LINQ還是不去LINQ
不要誤會我的意思。 每當我在LINQ手冊中尋找靈感時,我都會強烈希望在項目中進行嘗試。 它看起來很棒,而且設計合理。 關于Stack Overflow也有很多有趣的LINQ問題 。 我不介意在Java中使用LINQ ,但是我想提醒讀者,LINQ 不是 SQL。 如果您想控制SQL,則LINQ或LINQesque API可能是錯誤的選擇,原因有兩個:
選擇LINQ或其“ Java實現”時,請注意上述內容! 使用SQL(即JDBC, jOOQ或MyBatis )進行數據提取,并使用Java API(例如Java 8的Stream API)進行內存中后處理可能會更好。
類似于LINQ的庫在Java,Scala中建模SQL
- jOOQ: http : //www.jooq.org
- Sqltyped: https : //github.com/jonifreeman/sqltyped
類似于LINQ的庫在Java,Scala中抽象化SQL語法和數據存儲
- Quaere: http ://quaere.codehaus.org
- JaQu: http ://www.h2database.com/html/jaqu.html
- Linq4j: https : //github.com/julianhyde/linq4j
- 光滑: http : //slick.typesafe.com/
翻譯自: https://www.javacodegeeks.com/2013/07/linq-and-java.html
總結
- 上一篇: 如何在Mac电脑上把WiFi设置成热点电
- 下一篇: 科大讯飞宣布讯飞星火即日起向全民开放,能