Phalcon Query Language (PHQL) ============================= 译者注:å¦è¿‡JAVA,略懂Hibernate的人应该会知é“,hibernate是javaeeä¸ä¸€ä¸ªéžå¸¸æµç¨‹çš„ORM软件,它其ä¸ç”Ÿæˆçš„ä¸é—´è¯å¥å°±å«åšHQL。 Phalcon查询è¯è¨€ï¼Œä¹Ÿå¯ä»¥å«PhalconQL或PHQL,是一个高层次的,å…è®¸ä½ ä½¿ç”¨ä¸€ç§ç±»SQLè¯è¨€çš„æ–¹å¼çš„一ç§SQL方言。PHQL是一个用Cè¯è¨€ç¼–写的SQLè¯æ³•分æžå™¨ã€‚ 为了达到尽å¯èƒ½é«˜çš„æ€§èƒ½ï¼ŒPhalconæä¾›äº†ä¸€ä¸ªåˆ†æžå™¨ï¼Œä½¿ç”¨äº†å’Œ SQLite_ 相åŒçš„æŠ€æœ¯ã€‚该技术æä¾›äº†ä¸€ä¸ªå°åž‹çš„内å˜åˆ†æžå™¨ï¼Œå…·æœ‰éžå¸¸ä½Žçš„内å˜å ç”¨ï¼ŒåŒæ—¶ä¹Ÿæ˜¯çº¿ç¨‹å®‰å…¨çš„。 è§£æžå™¨é¦–å…ˆæ£€æŸ¥ä¼ é€’è¿‡æ¥çš„PHQLè¯å¥ï¼Œç„¶åŽæŠŠå®ƒä»¬è½¬åŒ–æˆä¸€ç§ä¸é—´æ€§çš„è¯å¥ï¼Œæœ€åŽå†å°†å…¶è½¬æ¢ä¸ºç›¸åº”çš„RDBMS所需è¦çš„SQL方言。 在PHQLä¸ï¼Œæˆ‘们已ç»å®žçŽ°äº†ä¸€ç³»åˆ—çš„åŠŸèƒ½ï¼Œä»¥ä¿è¯ä½ 在访问数æ®åº“时是安全的: * Bound parameters are part of the PHQL language helping you to secure your code * PHQL only allows one SQL statement to be executed per call preventing injections * PHQL ignores all SQL comments which are often used in SQL injections * PHQL only allows data manipulation statements, avoiding altering or dropping tables/databases by mistake or externally without authorization * PHQL implements a high level abstraction allowing you handling models as tables and class attributes as fields 使用示例 ------------- 为了更好的展示PHQL是如何工作的,我们将使用模型 “Cars†和 “Brandsâ€ï¼š .. code-block:: php <?php class Cars extends Phalcon\Mvc\Model { public $id; public $name; public $brand_id; public $price; public $year; public $style; /** * This model is mapped to the table sample_cars */ public function getSource() { return 'sample_cars'; } /** * A car only has a Brand, but a Brand have many Cars */ public function initialize() { $this->belongsTo('brand_id', 'Brands', 'id'); } } æ¯ä¸ªCaråªæœ‰ä¸€ä¸ªBrand,一个Brand有多个Cars: .. code-block:: php <?php class Brands extends Phalcon\Mvc\Model { public $id; public $name; /** * The model Brands is mapped to the "sample_brands" table */ public function getSource() { return 'sample_brands'; } /** * A Brand can have many Cars */ public function initialize() { $this->hasMany('id', 'Cars', 'brand_id'); } } Creating PHQL Queries --------------------- PHQL查询å¯ä»¥é€šè¿‡å®žä¾‹åŒ– :doc:`Phalcon\\Mvc\\Model\\Query <../api/Phalcon_Mvc_Model_Query>` æ¥åˆ›å»ºï¼š .. code-block:: php <?php // Instantiate the Query $query = new Phalcon\Mvc\Model\Query("SELECT * FROM Cars"); // Pass the DI container $query->setDI($di); // Execute the query returning a result if any $robots = $query->execute(); 在控制器或视图文件ä¸ï¼Œå®ƒå¯ä»¥ä½¿ç”¨æœåС容噍ä¸çš„一个注入æœåŠ¡ :doc:`models manager <../api/Phalcon_Mvc_Model_Manager>` æ¥è½»æ¾çš„实现create/execute .. code-block:: php <?php $query = $this->modelsManager->createQuery("SELECT * FROM Cars"); $robots = $query->execute(); 或者åƒä¸‹é¢è¿™æ ·ï¼š .. code-block:: php <?php $robots = $this->modelsManager->executeQuery("SELECT * FROM Cars"); Selecting Records ----------------- 作为大家所熟悉的SQL,PHQLå…è®¸ä½ åœ¨æŸ¥è¯¢ä¸ä½¿ç”¨SELECTè¯å¥ï¼Œåªæ˜¯éœ€è¦ä½¿ç”¨æ¨¡åž‹ç±»çš„åç§°æ¥æ›¿ä»£æ•°æ®è¡¨å: .. code-block:: php <?php $query = $manager->createQuery("SELECT * FROM Cars ORDER BY Cars.name"); $query = $manager->createQuery("SELECT Cars.name FROM Cars ORDER BY Cars.name"); 带有命åç©ºé—´çš„æ¨¡åž‹ç±»åŒæ ·å¯ä»¥ï¼š .. code-block:: php <?php $phql = "SELECT * FROM Formula\Cars ORDER BY Formula\Cars.name"; $query = $manager->createQuery($phql); $phql = "SELECT Formula\Cars.name FROM Formula\Cars ORDER BY Formula\Cars.name"; $query = $manager->createQuery($phql); $phql = "SELECT c.name FROM Formula\Cars c ORDER BY c.name"; $query = $manager->createQuery($phql); Phalcon支æŒå¤§éƒ¨åˆ†çš„SQLæ ‡å‡†ï¼Œç”šè‡³æ˜¯éžæ ‡å‡†æŒ‡ä»¤ï¼Œå¦‚,LIMIT: .. code-block:: php <?php $phql = "SELECT c.name FROM Cars AS c " . "WHERE c.brand_id = 21 ORDER BY c.name LIMIT 100"; $query = $manager->createQuery($phql); Results Types ^^^^^^^^^^^^^ æ ¹æ®æˆ‘ä»¬æŸ¥è¯¢åˆ—çš„ç±»åž‹ï¼Œè¿”å›žçš„ç»“æžœç±»åž‹ä¼šç¨æœ‰ä¸åŒã€‚å¦‚æžœä½ æ£€ç´¢ä¸€ä¸ªæ•´ä½“å¯¹è±¡ï¼Œå®ƒå°†è¿”å›ž :doc:`Phalcon\\Mvc\\Model\\Resultset\\Simple <../api/Phalcon_Mvc_Model_Resultset_Simple>` 的对象实例。这ç§ç»“果集是一组完整的模型对象: .. code-block:: php <?php $phql = "SELECT c.* FROM Cars AS c ORDER BY c.name"; $cars = $manager->executeQuery($phql); foreach ($cars as $car) { echo "Name: ", $car->name, "\n"; } è¿™æ˜¯å®Œå…¨ä¸€æ ·çš„ï¼š .. code-block:: php <?php $cars = Cars::find(array("order" => "name")); foreach ($cars as $car) { echo "Name: ", $car->name, "\n"; } 完整的对象å¯ä»¥è¢«ä¿®æ”¹å’Œé‡æ–°ä¿å˜åˆ°æ•°æ®åº“ï¼Œå› ä¸ºä»–ä»¬ä»£è¡¨ç€å…³è”æ•°æ®è¡¨çš„一个完整记录。有一些其他类型的查询ä¸è¿”回完整的对象,例如: .. code-block:: php <?php $phql = "SELECT c.id, c.name FROM Cars AS c ORDER BY c.name"; $cars = $manager->executeQuery($phql); foreach ($cars as $car) { echo "Name: ", $car->name, "\n"; } æˆ‘ä»¬åªæŸ¥è¯¢äº†æ•°æ®è¡¨ä¸çš„æŸäº›å—æ®µï¼Œå› æ¤ï¼Œè¿™ä¸èƒ½ç®—æ˜¯ä¸€ä¸ªå®Œæ•´çš„å¯¹è±¡ã€‚åœ¨è¿™ç§æƒ…况下,也返回 :doc:`Phalcon\\Mvc\\Model\\Resultset\\Simple <../api/Phalcon_Mvc_Model_Resultset_Simple>` 的实例对象。然而,这个对象åªåŒ…å«ä¸¤åˆ—属性值。 这些值ä¸ä»£è¡¨å®Œæ•´çš„å¯¹è±¡ï¼Œæˆ‘ä»¬ç§°ä»–ä»¬ä¸ºæ ‡é‡ã€‚PHQLå…è®¸ä½ æŸ¥è¯¢å„ç§ç±»åž‹çš„æ ‡é‡ï¼Œå¦‚fields,functions,literals, expressionsç‰ .. code-block:: php <?php $phql = "SELECT CONCAT(c.id, ' ', c.name) AS id_name FROM Cars AS c ORDER BY c.name"; $cars = $manager->executeQuery($phql); foreach ($cars as $car) { echo $car->id_name, "\n"; } 我们既å¯ä»¥åªæŸ¥è¯¢å®Œæ•´çš„å¯¹è±¡æˆ–æ ‡é‡ï¼Œä¹Ÿå¯ä»¥åŒæ—¶æŸ¥è¯¢ä»–们: .. code-block:: php <?php $phql = "SELECT c.price*0.16 AS taxes, c.* FROM Cars AS c ORDER BY c.name"; $result = $manager->executeQuery($phql); åœ¨è¿™ç§æƒ…况下,返回的是 :doc:`Phalcon\\Mvc\\Model\\Resultset\\Complex <../api/Phalcon_Mvc_Model_Resultset_Complex>` 的实例对象,这å…è®¸åŒæ—¶è®¿é—®å®Œæ•´å¯¹è±¡å’Œæ ‡é‡ï¼š .. code-block:: php <?php foreach ($result as $row) { echo "Name: ", $row->cars->name, "\n"; echo "Price: ", $row->cars->price, "\n"; echo "Taxes: ", $row->taxes, "\n"; } æ ‡é‡çš„å±žæ€§å€¼æ˜ å°„åˆ°"row"ä¸Šï¼Œè€Œå®Œæ•´çš„å¯¹è±¡åˆ™æ˜¯è¢«æ˜ å°„åˆ°ä¸Žå®ƒç›¸å…³çš„æ¨¡åž‹å¯¹è±¡ä¸Šã€‚ Joins ^^^^^ 使用PHQLå¯ä»¥å¾ˆæ–¹ä¾¿çš„通过多个模型æ¥èŽ·å–æ•°æ®ï¼ŒPhalcon支æŒå¤§å¤šæ•°ç±»åž‹çš„Joins。我们在模型ä¸å®šä¹‰çš„关系,在使用PHQLæ—¶ä¼šè‡ªåŠ¨çš„æ·»åŠ åˆ°æ¡ä»¶ä¸Šï¼š .. code-block:: php <?php $phql = "SELECT Cars.name AS car_name, Brands.name AS brand_name FROM Cars JOIN Brands"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo $row->car_name, "\n"; echo $row->brand_name, "\n"; } 默认情况下,将使用INNER JOIN的方å¼ï¼Œä½ 也å¯ä»¥åœ¨æŸ¥è¯¢ä¸ä½¿ç”¨å…¶ä»–类型的JOIN: .. code-block:: php <?php $phql = "SELECT Cars.*, Brands.* FROM Cars INNER JOIN Brands"; $rows = $manager->executeQuery($phql); $phql = "SELECT CCars.*, Brands.* FROM Cars LEFT JOIN Brands"; $rows = $manager->executeQuery($phql); $phql = "SELECT Cars.*, Brands.* FROM Cars LEFT OUTER JOIN Brands"; $rows = $manager->executeQuery($phql); $phql = "SELECT Cars.*, Brands.* FROM Cars CROSS JOIN Brands"; $rows = $manager->executeQuery($phql); 有å¯èƒ½çš„è¯ï¼Œåœ¨JOIN䏿‰‹å·¥è®¾ç½®SQLæ¡ä»¶ï¼š .. code-block:: php <?php $phql = "SELECT Cars.*, Brands.* FROM Cars INNER JOIN Brands ON Brands.id = Cars.brands_id"; $rows = $manager->executeQuery($phql); åŒæ—¶ï¼ŒJoins还å¯ä»¥åœ¨ä½¿ç”¨ä»¥ä¸‹æ–¹å¼ï¼š .. code-block:: php <?php $phql = "SELECT Cars.*, Brands.* FROM Cars, Brands WHERE Brands.id = Cars.brands_id"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo "Car: ", $row->cars->name, "\n"; echo "Brand: ", $row->brands->name, "\n"; } 如果在查询时使用了别å,获å–属性值将使用别åçš„åç§°åšä¸ºrowçš„å称: .. code-block:: php <?php $phql = "SELECT c.*, b.* FROM Cars c, Brands b WHERE b.id = c.brands_id"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo "Car: ", $row->c->name, "\n"; echo "Brand: ", $row->b->name, "\n"; } Aggregations ^^^^^^^^^^^^ 下é¢çš„示例将展示如何在PHQLä¸ä½¿ç”¨èšåˆï¼š .. code-block:: php <?php // How much are the prices of all the cars? $phql = "SELECT SUM(price) AS summatory FROM Cars"; $row = $manager->executeQuery($phql)->getFirst(); echo $row['summatory']; // How many cars are by each brand? $phql = "SELECT Cars.brand_id, COUNT(*) FROM Cars GROUP BY Cars.brand_id"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo $row->brand_id, ' ', $row["1"], "\n"; } // How many cars are by each brand? $phql = "SELECT Brands.name, COUNT(*) FROM Cars JOIN Brands GROUP BY 1"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo $row->name, ' ', $row["1"], "\n"; } $phql = "SELECT MAX(price) AS maximum, MIN(price) AS minimum FROM Cars"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo $row["maximum"], ' ', $row["minimum"], "\n"; } // Count distinct used brands $phql = "SELECT COUNT(DISTINCT brand_id) AS brandId FROM Cars"; $rows = $manager->executeQuery($phql); foreach ($rows as $row) { echo $row->brandId, "\n"; } æ¡ä»¶(Conditions) ^^^^^^^^^^^^^^^^^^^^^ æ¡ä»¶çš„作用是å…è®¸ä½ è¿‡æ»¤æŸ¥è¯¢å†…å®¹ï¼ŒWHEREæ¡ä»¶å¯ä»¥è¿™æ ·ä½¿ç”¨ï¼š .. code-block:: php <?php // Simple conditions $phql = "SELECT * FROM Cars WHERE Cars.name = 'Lamborghini Espada'"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.price > 10000"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE TRIM(Cars.name) = 'Audi R8'"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.name LIKE 'Ferrari%'"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.name NOT LIKE 'Ferrari%'"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.price IS NULL"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.id IN (120, 121, 122)"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.id NOT IN (430, 431)"; $cars = $manager->executeQuery($phql); $phql = "SELECT * FROM Cars WHERE Cars.id BETWEEN 1 AND 100"; $cars = $manager->executeQuery($phql); æ¤å¤–,PHQLçš„å¦ä¸€ç‰¹ç‚¹ï¼Œprepared傿•°è‡ªåŠ¨è½¬ä¹‰ç”¨æˆ·è¾“å…¥æ•°æ®ï¼Œä¸‹é¢å°†ä»‹ç»çš„æ˜¯ä¸Žå®‰å…¨ç›¸å…³ï¼š .. code-block:: php <?php $phql = "SELECT * FROM Cars WHERE Cars.name = :name:"; $cars = $manager->executeQuery($phql, array("name" => 'Lamborghini Espada')); $phql = "SELECT * FROM Cars WHERE Cars.name = ?0"; $cars = $manager->executeQuery($phql, array(0 => 'Lamborghini Espada')); Inserting Data -------------- PHQL是使用熟悉的INSERTè¯å¥æ’入数æ®ï¼š .. code-block:: php <?php // Inserting without columns $phql = "INSERT INTO Cars VALUES (NULL, 'Lamborghini Espada', " . "7, 10000.00, 1969, 'Grand Tourer')"; $manager->executeQuery($phql); // Specifyng columns to insert $phql = "INSERT INTO Cars (name, brand_id, year, style) " . "VALUES ('Lamborghini Espada', 7, 1969, 'Grand Tourer')"; $manager->executeQuery($phql); // Inserting using placeholders $phql = "INSERT INTO Cars (name, brand_id, year, style) " . "VALUES (:name:, :brand_id:, :year:, :style)"; $manager->executeQuery($sql, array( 'name' => 'Lamborghini Espada', 'brand_id' => 7, 'year' => 1969, 'style' => 'Grand Tourer', ) ); Phalconä¸ä¸åªæ˜¯ç”¨PHQLè¯å¥è½¬æ¢ä¸ºSQLè¯å¥çš„。如果我们是手工创建模型对象,里é¢çš„æ‰€æœ‰äº‹ä»¶åŠå®šä¹‰çš„ä¸šåŠ¡è§„åˆ™éƒ½ä¼šè¢«æ‰§è¡Œã€‚çŽ°åœ¨ï¼Œæˆ‘ä»¬æ·»åŠ ä¸€ä¸ªæ¨¡åž‹Cars的业务规则,让carçš„ä»·æ ¼ä¸ä½ŽäºŽ$ 10,000: .. code-block:: php <?php use Phalcon\Mvc\Model\Message; class Cars extends Phalcon\Mvc\Model { public function beforeCreate() { if ($this->price < 10000) { $this->appendMessage(new Message("A car cannot cost less than $ 10,000")); return false; } } } 如果我们在模型ä¸ä½¿ç”¨ä»¥ä¸‹çš„INSERTè¯å¥ï¼ŒINSERTæ“ä½œå°†ä¸æˆåŠŸï¼Œå› ä¸ºä»·æ ¼ä¸ç¬¦åˆå®šä¹‰çš„规则: .. code-block:: php <?php $phql = "INSERT INTO Cars VALUES (NULL, 'Nissan Versa', 7, 9999.00, 2012, 'Sedan')"; $result = $manager->executeQuery($phql); if ($result->success() == false) { foreach ($result->getMessages() as $message) { echo $message->getMessage(); } } æ›´æ–°æ•°æ®(Updating Data) ----------------------------- 更新一行记录和æ’入一行记录éžå¸¸ç›¸ä¼¼ã€‚æ£å¦‚ä½ æ‰€çŸ¥é“的,更新数æ®è®°å½•的指令是UPDATE。当更新一行记录时,对应的模型事件将被执行。 .. code-block:: php <?php // Updating a single column $phql = "UPDATE Cars SET price = 15000.00 WHERE id = 101"; $manager->executeQuery($phql); // Updating multiples columns $phql = "UPDATE Cars SET price = 15000.00, type = 'Sedan' WHERE id = 101"; $manager->executeQuery($phql); // Updating multiples rows $phql = "UPDATE Cars SET price = 7000.00, type = 'Sedan' WHERE brands_id > 5"; $manager->executeQuery($phql); // Using placeholders $phql = "UPDATE Cars SET price = ?0, type = ?1 WHERE brands_id > ?2"; $manager->executeQuery( $phql, array( 0 => 7000.00, 1 => 'Sedan', 2 => 5 ) ); åˆ é™¤æ•°æ®(Deleting Data) ------------------------ å½“åˆ é™¤æ•°æ®æ—¶ï¼Œå¯¹åº”的模型事件将被执行: .. code-block:: php <?php // Deleting a single row $phql = "DELETE FROM Cars WHERE id = 101"; $manager->executeQuery($phql); // Deleting multiple rows $phql = "DELETE FROM Cars WHERE id > 100"; $manager->executeQuery($phql); // Using placeholders $phql = "DELETE FROM Cars WHERE id BETWEEN :initial: AND :final:"; $manager->executeQuery( $phql, array( 'initial' => 1, 'final' => '100 ) ); 使用Query Builder创建queries(Creating queries using the Query Builder) ------------------------------------------------------------------------- Query Builderå¯ä»¥åˆ›å»ºä¸€ä¸ªPHQL query,而ä¸éœ€è¦ç¼–写PHQLè¯å¥äº†ï¼ŒåŒæ—¶Query Builder对IDE工具是å‹å¥½çš„(å¯ä»¥è‡ªåЍæç¤ºï¼‰ï¼š .. code-block:: php <?php $manager->createBuilder() >join('RobotsParts'); ->limit(20); ->order('Robots.name') ->getQuery() ->execute(); ä¸Žä¸‹é¢æ˜¯ç›¸åŒçš„: .. code-block:: php <?php $phql = "SELECT Robots.* FROM Robots JOIN RobotsParts p ORDER BY Robots.name LIMIT 20"; $result = $manager->executeQuery($phql); 更多关于query builder的示例: .. code-block:: php <?php $builder->from('Robots') // 'SELECT Robots.* FROM Robots' // 'SELECT Robots.*, RobotsParts.* FROM Robots, RobotsParts' $builder->from(array('Robots', 'RobotsParts')) // 'SELECT * FROM Robots' $phql = $builder->columns('*') ->from('Robots') // 'SELECT id, name FROM Robots' $builder->columns(array('id', 'name')) ->from('Robots') // 'SELECT id, name FROM Robots' $builder->columns('id, name') ->from('Robots') // 'SELECT Robots.* FROM Robots WHERE Robots.name = "Voltron"' $builder->from('Robots') ->where('Robots.name = "Voltron"') // 'SELECT Robots.* FROM Robots WHERE Robots.id = 100' $builder->from('Robots') ->where(100) // 'SELECT Robots.* FROM Robots GROUP BY Robots.name' $builder->from('Robots') ->groupBy('Robots.name') // 'SELECT Robots.* FROM Robots GROUP BY Robots.name, Robots.id' $builder->from('Robots') ->groupBy(array('Robots.name', 'Robots.id')) // 'SELECT Robots.name, SUM(Robots.price) FROM Robots GROUP BY Robots.name' $builder->columns(array('Robots.name', 'SUM(Robots.price)')) ->from('Robots') ->groupBy('Robots.name') // 'SELECT Robots.name, SUM(Robots.price) FROM Robots // GROUP BY Robots.name HAVING SUM(Robots.price) > 1000' $builder->columns(array('Robots.name', 'SUM(Robots.price)')) ->from('Robots') ->groupBy('Robots.name') ->having('SUM(Robots.price) > 1000') // 'SELECT Robots.* FROM Robots JOIN RobotsParts'); $builder->from('Robots') ->join('RobotsParts') // 'SELECT Robots.* FROM Robots JOIN RobotsParts AS p'); $builder->from('Robots') ->join('RobotsParts', null, 'p') // 'SELECT Robots.* FROM Robots JOIN RobotsParts ON Robots.id = RobotsParts.robots_id AS p'); $builder->from('Robots') ->join('RobotsParts', 'Robots.id = RobotsParts.robots_id', 'p') // 'SELECT Robots.* FROM Robots // JOIN RobotsParts ON Robots.id = RobotsParts.robots_id AS p // JOIN Parts ON Parts.id = RobotsParts.parts_id AS t' $builder->from('Robots') ->join('RobotsParts', 'Robots.id = RobotsParts.robots_id', 'p') ->join('Parts', 'Parts.id = RobotsParts.parts_id', 't') // 'SELECT r.* FROM Robots AS r' $builder->addFrom('Robots', 'r') // 'SELECT Robots.*, p.* FROM Robots, Parts AS p' $builder->from('Robots') ->addFrom('Parts', 'p') // 'SELECT r.*, p.* FROM Robots AS r, Parts AS p' $builder->from(array('r' => 'Robots')) ->addFrom('Parts', 'p') // 'SELECT r.*, p.* FROM Robots AS r, Parts AS p'); $builder->from(array('r' => 'Robots', 'p' => 'Parts')) // 'SELECT Robots.* FROM Robots LIMIT 10' $builder->from('Robots') ->limit(10) // 'SELECT Robots.* FROM Robots LIMIT 10 OFFSET 5' $builder->from('Robots') ->limit(10, 5) .. _SQLite: http://en.wikipedia.org/wiki/Lemon_Parser_Generator