2012-07-17 138 views
6

有人可以提供一些明確的(事實支持)理由來使用/學習DQL與SQL,當需要一個自定義查詢時使用Doctrine Classes?使用Doctrine使用DQL而不是SQL有什麼好處?

我覺得,如果我不能使用ORM的內置關聯功能來實現的東西我平時寫在擴展學說或DoctrineTable類的定製方法。在這種方法中,將所需的數據寫入直接的SQL(使用具有適當的準備語句/注入保護等的PDO)。 DQL看起來像學習/調試/維護的附加語言似乎沒有提供足夠令人信服的理由在大多數常見情況下使用。 DQL似乎並不比SQL複雜得多,因爲我們懷疑如果沒有紮實的SQL理解,就可以有效地使用DQL。大多數核心SQL語法端口在您使用PHP的最常用數據庫中相當好。

我在想什麼/忽略?我確信有一個原因,但我想聽聽那些有意使用它的人,以及嘗試使用plain-ole SQL的好處。

我不是在尋找支持的ORM的說法,只是DQL需要做核心「得到逐關係」型需求之外的東西,在傳統的LAMP設置時(使用MySQL,Postgres的,等等。 )

+3

我沒有事實支持的參數,但是我發現名稱關係比聯接條件更容易使用,不易出錯並且編寫起來很繁瑣。 – 2012-07-17 20:42:23

回答

3

說實話,我學會了SQL使用Doctrine1.2 :)我甚至沒有意識到外鍵,級聯操作,像group_concat和許多其他許多複雜的功能。索引搜索也是非常好用和便利的事情,可以直接使用。

DQL要簡單得多,編寫和理解的代碼。例如,下面的查詢:

$query = ..... // some query for Categories 
    ->leftJoin("c.Products p") 

它會做左類別和產品之間的連接,你不必寫在p.category_id = c.id。

而且如果將來你從一個-2-許多變化的關係,讓我們說很多-2-許多,同樣的查詢將沒有任何變化在所有的工作。主義會照顧到這一點。如果你使用SQL來完成這項工作,那麼所有的查詢都必須被修改,以包含那個中間的2-many表。

+0

+1,尤其是對象之間的關係(外鍵)已經連接在我收到回覆的基礎類 – KJA 2012-07-19 08:59:11

+1

@Zeljko中,您對關於改變關係類型的答案的最後一點是對我的情況唯一有吸引力的答案。我並不關心爲什麼對於那些不瞭解關係數據庫的工作原理的人來說,這對於初學者來說並不總是最好的。另外,既然你注意到了ON子句......有時候你想添加除'ON'子句中的鍵之外的其他標準 - 就我所知,DQL不支持這一點。這是您需要做的大部分工作都很容易的例子,但在某些情況下極難使用。 – Ray 2012-07-20 13:41:18

+0

你說得對,你會有附加條款。在這種情況下,DQL提供'WITH'語句。是的;那個人也可以同時使用一對一,一對多,多對多......不用改變代碼。 我的建議:嘗試一下。一旦你迷上了,你將永遠不會回頭。這就像駕駛梅賽德斯頂級賽車與底線級別Yugo一樣。兩者都會將你從A點帶到B點,但我看不到爲Yugo形成的線條。 – Zeljko 2012-07-21 14:29:23

2

我發現DQL更具可讀性和方便。如果你正確地配置它,連接對象會更容易,查詢將更容易編寫。

您的代碼將很容易遷移到任何RDBMS。

而且最重要的,是DQL對象查詢語言對象模型,而不是你的關係模式。

+0

我認爲你的第一個是定性的 - 我已經看到真正複雜/複雜的DQL來完成一個簡單的SQL查詢可以解決的任務。你的第二點我完全同意,但正如我的問題所指出的那樣,對於涵蓋DQL所能完成的所有事情所需的基本SQL而言,並不值得關注。你最後一點是最有說服力的方法。好的,這是一個查詢語言,而不是底層存儲的對象。什麼看作是查詢語言的核心優勢?它會提高性能嗎?它是否支持經過充分審查的面向對象模式?它是否允許更高效/更好的代碼? – Ray 2012-07-18 12:47:49

+0

@Ray在使用Doctrine 1.2之後,對性能確實有害。 – KJA 2012-07-19 09:05:21

+0

你有沒有任何參考資料可以理解教義生成的模型類(TestTable,BastTest,Test)以及如何正確處理它們,誰在控制器中調用? 可以請你訪問我的問題http://stackoverflow.com/questions/11529224/doctrine-table-vs-class-that-extends-from-baseclass – KJA 2012-07-19 10:26:24

1

使用DQL可以幫助您處理對象。 的情況下,插入databae,你會插入對象

$test = new Test(); 
$test->attr = 'test'; 
$test->save(); 

從databae選擇的情況下,你會選擇一個數組,然後你可以填寫在你的對象

public function getTestParam($testParam) 
    { 
     $q=Doctrine_Query::create() 
       ->select('t.test_id , t.attr') 
       ->from('Test t ') 
      $p = $q->execute(); 
      return $p; 
    } 

您可以檢查該教義文檔的更多細節

1

Zeljko的回答很有用。

使用DQL而不是原始SQL的最重要原因(在我的書中):Doctrine將實體與它在數據庫中的存儲方式分離開來,這意味着實體不必更改爲底層存儲更改。這反過來又意味着,如果您希望對底層存儲進行更改(即重命名列,更改關係),則不必觸摸DQL,因爲在DQL中,您使用實體屬性(而這隻發生在根據你當前的映射,在後臺進行編譯以糾正SQL)。

+0

在上個月的應用程序工作並對數據庫進行了許多更改之後,我同意這個答案。 – kiwicomb123 2018-01-10 00:05:32

相關問題