Java 順序員容易犯的10個SQL錯誤。本站提示廣大學習愛好者:(Java 順序員容易犯的10個SQL錯誤)文章只能為提供參考,不一定能成為您想要的結果。以下是Java 順序員容易犯的10個SQL錯誤正文
Java順序員編程時需求混合面向對象思想和普通命令式編程的辦法,能否完滿的將兩者結合起來完全得依托編程人員的水准:
但當Java順序員寫SQL語句時,一切都不一樣了。SQL是闡明性言語而非面向對象或是命令式編程言語。在SQL中要寫個查詢語句是很復雜的。但在Java裡相似的語句卻不容易,由於順序員不只要重復思索編程范式,而且也要思索算法的問題。
上面是Java順序員在寫SQL時常犯的錯誤(沒有特定的順序):
1.忘掉NULL
Java順序員寫SQL時對NULL的曲解能夠是最大的錯誤。也許是由於(並非獨一理由)NULL也稱作UNKNOWN。假如被稱作UNKNOWN,這還好了解些。另一個緣由是,當你從數據庫拿東西或是綁定變量時,JDBC將SQL NULL 和Java中的null對應了起來。這樣招致了NULL = NULL(SQL)和null=null(Java)的曲解。
關於NULL最大的曲解是當NULL被用作行值表達式完好性約束條件時。
另一個曲解呈現在關於NULL 在 NOT IN anti-joins的使用中。
處理辦法:
好好的訓練你自己。當你寫SQL時要不停得想到NULL的用法:
很少有Java開發者能將SQL了解的很好.偶然運用的JOIN,還有乖僻的UNION,好吧.但是關於窗口函數呢?還有對集合停止分組呢?許多的Java開發者將SQL數據加載到內存中,將這些數據轉換成某些相近的集合類型,然後再那些集合下面運用邊界循環控制構造(至多在Java8的集合晉級以前)執行令人生厭的數學運算.
但是一些SQL數據庫支持先進的(而且是SQL規范支持的!)OLAP特性,這一特性表現更好而且寫起來也愈加方便.一個(並不怎樣規范的)例子就是Oracle超棒的MODEL分句.只讓數據庫來做處置然後只把後果帶到Java內存中吧.由於畢竟一切十分聰明的家伙曾經對這些昂貴的產品停止了優化.因而實踐上,經過將OLAP移到數據庫,你將取得一下兩項益處:
完善的辦法:
每次你運用Java完成一個以數據為中心的算法時,問問自己:有沒有一種辦法可以讓數據庫替代為我做這種費事事.
3. 運用UNION替代UNION ALL
太可恥了,和UNION相比UNION ALL還需求額定的關鍵字。假如SQL規范曾經規則了支持,那麼能夠會更好點。
移除反復行不只很少需求(有時甚至是錯的),而且關於帶很多行的大數據集合會相當慢,由於兩個子select需求排序,而且每個元組也需求和它的子序列元組比擬。
留意即便SQL規范規則了INTERSECT ALL和EXCEPT ALL,很多數據庫會完成這些沒用的集合操作符。
處置辦法:
每次你寫UNION語句時,思索實踐上能否需求UNION ALL語句。
4.經過JDBC分頁技術給少量的後果停止分頁操作
大局部的數據庫都會支持一些分頁命令完成分頁效果,譬如LIMIT..OFFSET,TOP..START AT,OFFSET..FETCH語句等。即便沒有支持這些語句的數據庫,仍有能夠對ROWNUM(甲骨文)或許是ROW NUMBER() OVER()過濾(DB2,SQL Server2008等),這些比在內存中完成分頁更疾速。在處置少量數據中,效果尤其分明。
糾正:
僅僅運用這些語句,那麼一個工具(例如JOOQ)就可以模仿這些語句的操作。
5.在java內存中參加數據
從SQL的初期開端,當在SQL中運用JOIN語句時,一些開發者依舊有不安的覺得。這是源自對參加JOIN後會變慢的固有恐懼。假設基於本錢的優化選擇去完成嵌套循環,在創立一張銜接表源前,能夠加載一切的表在數據庫內存中,這能夠是真的。但是這事發作的概率太低了。經過適宜的預測,約束和索引,兼並銜接和哈希銜接的操作都是相當的快。這完全是是關於正確元數據(在這裡我不可以援用Tom Kyte的太多)。而且,能夠依然有不少的Java開發人員加載兩張表經過分開查詢到一個映射中,並且在某種水平上把他們加到了內存當中。
糾正:
假設你在各個步驟中有從各種表的查詢操作,好好想想能否可以表達你的查詢操作在單條語句中。
6.在一個暫時的笛卡爾積集合中運用 DISTINCT 或 UNION 消弭反復項
經過復雜的銜接,人們能夠會對SQL語句中扮演關鍵角色的一切關系得到概念。特別的,假如這觸及到多列外鍵關系的話,很有能夠會遺忘在JOIN .. ON子句中添加相關的判別。這會招致反復的記載,但或許只是在特殊的狀況下。有些開發者因而能夠選擇DISTINCT來消弭這些反復記載。從三個方面來說這是錯誤的:
處理辦法:
依據經歷,假如你取得了不需求的反復記載,還是反省你的JOIN判別吧。能夠在某個中央有一個很難察覺的笛卡爾積集合。
7. 不運用MERGE語句
這並不是一個過失,但是能夠是短少知識或許關於強悍的MERGE語句決心缺乏。一些數據庫了解其它方式的更新拔出(UPSERT)語句, 如 MYSQL的反復主鍵更新語句,但是MERGE在數據庫中確是很弱小,很重要,以致於大肆擴展SQL規范,例如SQL SERVER。
處理之道:
假如你運用像結合INSERT和UPDATE或許結合SELECT .. FOR UPDATE然後在INSERT或UPDATE等更新拔出時,請三思。你完全可以運用一個更復雜的MERGE語句來遠離冒險競爭條件。
8. 運用聚合函數替代窗口函數(window functions)
在引見窗口函數之前,在SQL中聚合數據意味著運用GROUP BY語句與聚合函數相映射。在很多情形下都任務得很好,如聚合數據需求稀釋慣例數據,那麼就在join子查詢中運用group查詢。
但是在SQL:2003中定義了窗口函數,這個在很多主流數據庫都完成了它。窗口函數可以在後果集上聚合數據,但是卻沒有分組。現實上,每個窗口函數都有自己的、獨立的PARTITION BY語句,這個工具關於顯示報告太TM好了。
運用窗口函數:
處理辦法:
當你在子查詢中運用GROUP BY語句時,請再三思索能否可以運用窗口函數完成。
9. 運用內存直接排序
SQL的ORDER BY語句支持很多類型的表達式,包括CASE語句,關於直接排序非常有用。你能夠重來不會在Java內存中排序數據,由於你會想:
處置辦法:
假如你在內存中排序任何SQL數據,請再三思索,能否不能在數據庫中排序。這關於數據庫分頁數據非常有用。
10. 一條一條的拔出少量紀錄
JDBC ”懂“批處置(batch),你應該不會忘了它。不要運用INSERT語句來一條一條的出入不計其數的記載,(由於)每次都會創立一個新的PreparedStatement對象。假如你的一切記載都拔出到同一個表時,那麼就創立一個帶有一條SQL語句以及附帶很多值集合的拔出批處置語句。你能夠需求在到達一定量的拔出記載後才提交來保證UNDO日志肥大,這依賴於你的數據庫和數據庫設置。
關注盛行國外網站
facebook:http://www.fb-on.com
facebook官網:http://www.facebookzh.com
facebook:http://www.cn-face-book.com
youtube:http://www.youtubezh.com
twitter:http://www.twitterzh.com
處置辦法:
總是運用批處置拔出少量數據。