告別枯燥的SQL查詢!使用FluentPDO簡化數據庫操作
您是否也厭倦了編寫SQL查詢?尤其是在時間緊迫的情況下。如果您和我一樣,那麼今天我們將學習一個非常酷炫的工具:FluentPDO。如果您不熟悉“PDO”這個術語,也不用擔心。它是一個非常簡單的概念:在PHP世界中,PDO代表持久化數據對象(Persistent Data Object),它幫助您抽象化一些基本的數據庫操作(如插入、更新、刪除等)。它是您與數據庫之間的一層抽象層。
結果呢?不再需要編寫SQL查詢了!這可能不是您見到的第一個這樣的項目:市面上有很多類似的項目,每個項目都有其關鍵特性。 FluentPDO的關鍵特性在於其強大的JOIN查詢構建器。
首先,我們需要一個示例項目來進行操作。讓我們考慮一下……一個簡單的多用戶願望清單怎麼樣?
會有很多用戶,每個用戶都有自己喜歡的產品。對於每個用戶,我們將存儲其名字、姓氏和註冊日期。對於每個商品,我們將存儲其名稱、品牌、價格和相關的用戶ID。
我將使用一個簡單的MySQL數據庫。以下是我們的數據結構:
以下是SQL轉儲(包含一些虛擬數據):
<code class="language-sql">CREATE TABLE IF NOT EXISTS items ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, brand varchar(100) NOT NULL, price decimal(10,2) NOT NULL, user_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO items (id, name, brand, price, user_id) VALUES (1, 'Last Awesome Phone', 'Awesome Brand', '550.00', 1), (2, 'Last Awesome TV', 'Awesome Brand', '1200.00', 1), (3, 'Fantastic E-Car', 'E-Cars Inc.', '80000.00', 2), (4, 'Fantastic E-Bike', 'E-Bikes Co. Ltd.', '16000.00', 2); CREATE TABLE IF NOT EXISTS users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, signup_date datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3; INSERT INTO users (id, first_name, last_name, signup_date) VALUES (1, 'Francesco', 'Malatesta', '2014-06-29 13:00:00'), (2, 'John', 'Foo Bar', '2014-06-20 11:16:39'); ALTER TABLE items ADD CONSTRAINT items_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id);</code>
注意:正如您很容易想像的那樣,這不是一個“完整的”項目。我們只是在嘗試FluentPDO,所以我們不會涵蓋諸如登錄、註冊或應用程序結構之類的內容。
您可以使用Composer安裝FluentPDO,將其作為依賴項包含在內:
<code class="language-json">"require": { ... "lichtner/fluentpdo": "dev-master" }</code>
完成後,您需要像這樣實例化它:
<code class="language-sql">CREATE TABLE IF NOT EXISTS items ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, brand varchar(100) NOT NULL, price decimal(10,2) NOT NULL, user_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO items (id, name, brand, price, user_id) VALUES (1, 'Last Awesome Phone', 'Awesome Brand', '550.00', 1), (2, 'Last Awesome TV', 'Awesome Brand', '1200.00', 1), (3, 'Fantastic E-Car', 'E-Cars Inc.', '80000.00', 2), (4, 'Fantastic E-Bike', 'E-Bikes Co. Ltd.', '16000.00', 2); CREATE TABLE IF NOT EXISTS users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, signup_date datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3; INSERT INTO users (id, first_name, last_name, signup_date) VALUES (1, 'Francesco', 'Malatesta', '2014-06-29 13:00:00'), (2, 'John', 'Foo Bar', '2014-06-20 11:16:39'); ALTER TABLE items ADD CONSTRAINT items_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id);</code>
您必須在PDO構造函數方法中指定您的連接詳細信息。在第一個參數中,在dbname=部分之後鍵入您的數據庫名稱,然後將您的用戶名和密碼分別作為第二個和第三個參數寫入。
然後,您將PDO對像作為參數傳遞給FluentPDO對象的構造函數。
就是這樣,FluentPDO不需要任何其他東西即可工作。無需額外配置。
我們已經有一些虛擬數據了。讓我們從SQL查詢的“Hello World”開始。一個簡單的SELECT,帶有一個WHERE子句,以及用戶主鍵ID作為參數來檢索基本信息。
<code class="language-json">"require": { ... "lichtner/fluentpdo": "dev-master" }</code>
這裡沒有什麼難理解的。 FluentPDO具有良好且易讀的語法,因此很容易理解我們在做什麼。
from()方法用於設置正確的表。 where()方法用於使用相同的名稱子句過濾我們的結果。默認情況下,在where()方法中,您只需指定字段名稱和值。 “=”是隱含的。當然,您也可以使用不同的比較運算符。在這種情況下,您必須將它們寫在字段名稱之後。
<code class="language-php">$pdo = new PDO("mysql:dbname=wishlist", "root", "password"); $fpdo = new FluentPDO($pdo);</code>
獲取結果非常容易:它們存儲在我們剛剛使用的$query對像中。您可以使用foreach循環迭代它,如示例所示。
在這種特定情況下(按主鍵ID搜索項目),我們也可以在from()方法中使用快捷方式:
<code class="language-php">$user_id = 1; $query = $fpdo->from('users')->where('id', $user_id); foreach($query as $row){ echo 'Hello, ' . $row['first_name'] . ' ' . $row['last_name'] . '!'; }</code>
讓我們看看比這更複雜的東西。
如果需要,您可以使用from()之後的select()方法選擇特定字段。您只需使用數組告訴FluentPDO您想要選擇哪些字段即可。
這是一個示例:
<code class="language-php">$fpdo->from('items')->where('price >', 1000);</code>
設置LIMIT和OFFSET參數以僅從數據庫中檢索一定數量的行非常容易。您可以像這樣使用limit()和offset()方法。
<code class="language-php">$query = fpdo->from('users', $user_id); // 将与...相同 $query = $fpdo->from('users')->where('id', $user_id);</code>
這兩個方法的唯一參數是一個整數,指定所需的值(對於limit(),是項目的數量;對於offset(),是要跳過的項目的數量)。
還提供了用於“HAVING”、“GROUP BY”和“ORDER BY”指令的方法。
讓我們用一些例子來看看它們。
orderBy()方法用於根據特定條件對結果進行排序。讓我們舉個例子:以下是按價格(從便宜到貴)對結果進行排序的方法。
<code class="language-php">$query = $fpdo->from('users')->select(array('first_name', 'last_name'))->where('id', $user_id);</code>
如果要反轉順序(從最貴到最便宜獲取結果),只需在選擇的列之後添加“DESC”即可。
<code class="language-php">// 选择前十个结果... $query = $fpdo->from('users')->where('id', $user_id)->limit(10)->offset(0);</code>
having()方法具有非常簡單的語法。在下面的示例中,我們過濾價格低於2000美元的每個商品。
<code class="language-php">$query = $fpdo->from('items')->orderBy('price');</code>
非常簡單。
您可以使用所需的任何比較運算符。
使用groupBy()方法,您可以使用特定字段作為條件對結果進行分組。這裡我們顯示每個品牌的商品數量。
<code class="language-sql">CREATE TABLE IF NOT EXISTS items ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, brand varchar(100) NOT NULL, price decimal(10,2) NOT NULL, user_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO items (id, name, brand, price, user_id) VALUES (1, 'Last Awesome Phone', 'Awesome Brand', '550.00', 1), (2, 'Last Awesome TV', 'Awesome Brand', '1200.00', 1), (3, 'Fantastic E-Car', 'E-Cars Inc.', '80000.00', 2), (4, 'Fantastic E-Bike', 'E-Bikes Co. Ltd.', '16000.00', 2); CREATE TABLE IF NOT EXISTS users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, signup_date datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3; INSERT INTO users (id, first_name, last_name, signup_date) VALUES (1, 'Francesco', 'Malatesta', '2014-06-29 13:00:00'), (2, 'John', 'Foo Bar', '2014-06-20 11:16:39'); ALTER TABLE items ADD CONSTRAINT items_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id);</code>
注意:您可以像在經典SQL中一樣為字段指定別名。
使用foreach不是獲取結果的唯一方法。如果我們只想從集合中檢索第一個結果怎麼辦?
只需使用fetch()方法:
<code class="language-json">"require": { ... "lichtner/fluentpdo": "dev-master" }</code>
您還可以獲取單個列,方法是指定其名稱作為參數。
<code class="language-php">$pdo = new PDO("mysql:dbname=wishlist", "root", "password"); $fpdo = new FluentPDO($pdo);</code>
使用fetchPairs(),您可以將結果作為關聯數組檢索。使用以下語法:
<code class="language-php">$user_id = 1; $query = $fpdo->from('users')->where('id', $user_id); foreach($query as $row){ echo 'Hello, ' . $row['first_name'] . ' ' . $row['last_name'] . '!'; }</code>
您將獲得如下輸出:
<code class="language-php">$fpdo->from('items')->where('price >', 1000);</code>
這是一個示例,使用用戶唯一ID和名字。
<code class="language-php">$query = fpdo->from('users', $user_id); // 将与...相同 $query = $fpdo->from('users')->where('id', $user_id);</code>
最後但並非最不重要的是fetchAll()方法。
以下是語法:
<code class="language-php">$query = $fpdo->from('users')->select(array('first_name', 'last_name'))->where('id', $user_id);</code>
使用fetchAll(),我們可以完全控制從結果中獲取的內容。第一個參數$index是用作索引的字段,$selectOnly用於指定要選擇的字段。
這是一個示例:
<code class="language-php">// 选择前十个结果... $query = $fpdo->from('users')->where('id', $user_id)->limit(10)->offset(0);</code>
注意:用作索引的列(在本例中為id)也包含在最終數組中。
好了,關於SELECT操作就足夠了。讓我們看看其他CRUD操作。
FluentPDO不僅僅是關於選擇東西。它還具有以簡單方式操作數據的類。
讓我們從INSERT操作開始。
<code class="language-php">$query = $fpdo->from('items')->orderBy('price');</code>
insertInto()方法用於指定要用於操作的表。然後,您必須使用values()方法分配所需的值(在本例中,它們存儲在$values關聯數組中)。
最後一步將是execute()方法,它將返回新記錄的主鍵。
如果需要,也可以使用此快捷方式:
<code class="language-php">$query = $fpdo->from('items')->orderBy('price DESC');</code>
UPDATE方法非常相似。讓我們看一個例子。
<code class="language-php">$query = $fpdo->from('items')->having('price <', 2000);</code>
使用set()方法,您可以為UPDATE操作指定新值。
使用where()方法,我們過濾受影響的行。還有一個快捷方式,如前所述。
DELETE操作更簡單。這是一個快速示例。
<code class="language-php">$query = $fpdo->from('items')->select('brand, COUNT(*) AS c')->groupBy('brand');</code>
如果要刪除知道其主鍵的記錄,可以使用上面的deleteFrom()快捷方式。
注意:正如您從這裡的示例中看到的,您必須使用execute()方法來運行DELETE查詢。如果不這樣做,您將不會更改數據庫中的任何內容。 INSERT和UPDATE也是如此。請記住這一點。
正如我之前告訴您的那樣,這類項目都有其獨特的特性。 FluentPDO也不例外:我們將分析其中的兩個特性:JOIN查詢構建器和調試器。
可能是FluentPDO最重要的獨特特性。如果要簡化工作並編寫更少的代碼,構建器非常有用。讓我們看看如何使用它。
我們將從使用FluentPDO編寫的“經典”JOIN查詢開始。
類似這樣:
<code class="language-php">$query = $fpdo->from('users'); $row = $query->fetch(); var_dump($row); // 将输出: // array(4) { ["id"]=> string(1) "1" ["first_name"]=> string(9) "Francesco" ["last_name"]=> string(9) "Malatesta" ["signup_date"]=> string(19) "2014-06-29 13:00:00" }</code>
好的:我們在特殊的leftJoin()方法中使用經典語法。還不錯。
但是,我們可以做得更好。如果在表結構中使用約定,則可以使用此代碼:
<code class="language-sql">CREATE TABLE IF NOT EXISTS items ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, brand varchar(100) NOT NULL, price decimal(10,2) NOT NULL, user_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO items (id, name, brand, price, user_id) VALUES (1, 'Last Awesome Phone', 'Awesome Brand', '550.00', 1), (2, 'Last Awesome TV', 'Awesome Brand', '1200.00', 1), (3, 'Fantastic E-Car', 'E-Cars Inc.', '80000.00', 2), (4, 'Fantastic E-Bike', 'E-Bikes Co. Ltd.', '16000.00', 2); CREATE TABLE IF NOT EXISTS users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, signup_date datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3; INSERT INTO users (id, first_name, last_name, signup_date) VALUES (1, 'Francesco', 'Malatesta', '2014-06-29 13:00:00'), (2, 'John', 'Foo Bar', '2014-06-20 11:16:39'); ALTER TABLE items ADD CONSTRAINT items_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id);</code>
很棒,對吧?好吧,快速確實很酷……但是智能呢?
看看這裡:
<code class="language-json">"require": { ... "lichtner/fluentpdo": "dev-master" }</code>
它變得更好了。
實際上,FluentPDO理解您想要做什麼,並使用您在select()方法中提供的帶有table.fieldname格式字符串的數據自動構建查詢。
您可以在這裡閱讀最後一個示例的最終構建查詢:
<code class="language-php">$pdo = new PDO("mysql:dbname=wishlist", "root", "password"); $fpdo = new FluentPDO($pdo);</code>
這看起來確實不錯。
如果需要,當然可以為字段創建別名:
<code class="language-php">$user_id = 1; $query = $fpdo->from('users')->where('id', $user_id); foreach($query as $row){ echo 'Hello, ' . $row['first_name'] . ' ' . $row['last_name'] . '!'; }</code>
FluentPDO帶有一個內置的調試器系統,您可以使用它來測試查詢並檢查它們。
它使用簡單的閉包系統。如果要使用調試,只需在連接代碼之後放置此代碼即可。
<code class="language-php">$fpdo->from('items')->where('price >', 1000);</code>
您可以根據需要自定義閉包,只需記住將$BaseQuery對像作為參數即可。
$BaseQuery對像是BaseQuery類的實例。
FluentPDO是一個小型簡單的項目。它絕對不適合每個項目,並且可以改進——尤其是在它已經休眠了六個月的情況下——但是對於小型/中型應用程序來說,它可能是一個不錯的選擇,以防您不想在遊戲中引入大型框架。由於它的一些特性,例如JOIN查詢構建器,它是一個不錯的折衷方案。
FluentPDO是一個使用PDO的PHP SQL查詢構建器。它為創建SQL查詢提供了一個簡單易用的界面,使開發人員更容易與數據庫交互。 FluentPDO對於那些不習慣編寫原始SQL查詢或想要加快開發過程的人特別有用。它支持所有SQL函數,並提供了一種安全的方法來防止SQL注入攻擊。
FluentPDO可以使用Composer(PHP的依賴項管理器)安裝。您可以通過運行命令composer require envms/fluentpdo
來安裝它。運行此命令後,Composer將把FluentPDO及其依賴項下載並安裝到您的項目中。
要使用FluentPDO連接到數據庫,您需要創建一個新的FluentPDO類實例。您可以通過將PDO實例傳遞給FluentPDO構造函數來實現。這是一個示例:
<code class="language-php">$query = fpdo->from('users', $user_id); // 将与...相同 $query = $fpdo->from('users')->where('id', $user_id);</code>
FluentPDO提供了一個簡單的界面來執行SELECT查詢。您可以使用from
方法指定表,並使用select
方法指定列。這是一個示例:
<code class="language-php">$query = $fpdo->from('users')->select(array('first_name', 'last_name'))->where('id', $user_id);</code>
要執行INSERT查詢,您可以使用insertInto
方法指定表,並使用values
方法指定值。這是一個示例:
<code class="language-sql">CREATE TABLE IF NOT EXISTS items ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, brand varchar(100) NOT NULL, price decimal(10,2) NOT NULL, user_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO items (id, name, brand, price, user_id) VALUES (1, 'Last Awesome Phone', 'Awesome Brand', '550.00', 1), (2, 'Last Awesome TV', 'Awesome Brand', '1200.00', 1), (3, 'Fantastic E-Car', 'E-Cars Inc.', '80000.00', 2), (4, 'Fantastic E-Bike', 'E-Bikes Co. Ltd.', '16000.00', 2); CREATE TABLE IF NOT EXISTS users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, signup_date datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3; INSERT INTO users (id, first_name, last_name, signup_date) VALUES (1, 'Francesco', 'Malatesta', '2014-06-29 13:00:00'), (2, 'John', 'Foo Bar', '2014-06-20 11:16:39'); ALTER TABLE items ADD CONSTRAINT items_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id);</code>
要執行UPDATE查詢,您可以使用update
方法指定表,使用set
方法指定新值,並使用where
方法指定條件。這是一個示例:
<code class="language-json">"require": { ... "lichtner/fluentpdo": "dev-master" }</code>
要執行DELETE查詢,您可以使用deleteFrom
方法指定表,並使用where
方法指定條件。這是一個示例:
<code class="language-php">$pdo = new PDO("mysql:dbname=wishlist", "root", "password"); $fpdo = new FluentPDO($pdo);</code>
當發生錯誤時,FluentPDO會拋出異常。您可以使用try-catch塊捕獲這些異常並相應地處理它們。這是一個示例:
<code class="language-php">$user_id = 1; $query = $fpdo->from('users')->where('id', $user_id); foreach($query as $row){ echo 'Hello, ' . $row['first_name'] . ' ' . $row['last_name'] . '!'; }</code>
FluentPDO提供了啟動、提交和回滾事務的方法。您可以分別使用beginTransaction
、commit
和rollBack
方法。這是一個示例:
<code class="language-php">$fpdo->from('items')->where('price >', 1000);</code>
FluentPDO提供了一個簡單的界面來連接表。您可以使用join
方法指定表和條件。這是一個示例:
<code class="language-php">$query = fpdo->from('users', $user_id); // 将与...相同 $query = $fpdo->from('users')->where('id', $user_id);</code>
以上是fluentpdo入門的詳細內容。更多資訊請關注PHP中文網其他相關文章!