sqrt-pro/query-builder

QueryBuilder 是 SQRT 框架的一部分

v0.1.0 2015-03-24 16:05 UTC

This package is not auto-updated.

Last update: 2024-09-24 03:40:06 UTC


README

Build Status Coverage Status Latest Stable Version License

用于构建 SELECT、UPDATE、INSERT、DELETE SQL 查询的库。

构建查询从创建 QueryBuilder 对象开始。可以立即为数据库中的表指定通用前缀

    $qb = new \SQRT\QueryBuilder('awesome_');

之后,可以创建查询对象,并按任何顺序组合所需的设置方法

重要:调用 where()having() 会将条件添加到“堆栈”。要清除之前添加的条件,需要显式调用方法,并指定 NULL:where(null)

SELECT

    $q = $qb->select('pages p')
      ->join('news n', 'p.id = n.parent_id', 'LEFT')
      ->columns('p.id', 'p.name', 'COUNT(n.id) AS news')
      ->where(array('n.is_active' => 1, 'p.status IS NOT NULL', 'age > :age'))
      ->bind('age', 50)
      ->groupby('p.id')
      ->having(array('news' => 10, 'SUM(`age`) >= :age'))
      ->orderby('p.id', 'news')
      ->limit(10);

DELETE

    $q = $qb->delete('pages')
      ->where(array('is_active' => 1, 'p.status IS NOT NULL', 'age > :age'))
      ->bind('age', 50)
      ->orderby('id')
      ->limit(10);

UPDATE

    $q = $qb->update('pages')
      ->setEqual('one', 1)
      ->setExpr('`weight` = `one` + :add')
      ->bind('add', 'hundred tons')
      ->where(array('name' => 'John', 'visited_at <= CURDATE()'));

INSERT

    $q = $qb->insert('pages')
      ->setEqual('name', 'John')
      ->setExpr('age = age + :ten')
      ->bind('ten', 10);

生成查询后,可以将其输出为带有替换值的完整 SQL 或为带有变量的准备好的表达式(prepared statements)

查询构建过程中指定的所有变量都将为 PDO 的值替换做好准备

仅使用命名变量,格式为 :name:id。不支持无名称的变量,如 ?

    $q = $qb->update('pages')
      ->setEqual('one', 1)
      ->setExpr('`weight` = `one` + :add')
      ->bind('add', 'hundred tons')
      ->where(array('name' => 'John'));

    $q->asSQL();            // UPDATE `awesome_pages` SET `one`=1, `weight` = `one` + "hundred tons" WHERE `name`="John"
    $q->asStatement();      // UPDATE `awesome_pages` SET `one`=:set_one, `weight` = `one` + :add WHERE `name`=:where_name
    $q->getBindedValues();  // Array([:where_name] => John, [:add] => hundred tons, [:set_one] => 1)

构建 WHERE 和 HAVING 条件

为了构建 SELECT 和 UPDATE 查询中的灵活 WHERE 和 HAVING 条件,使用 Conditions 对象,它可以方便地创建复杂的多级条件。然后可以将这些条件嵌入到查询中或相互嵌套。

可以创建一个包含条件的对象并将其传递给查询

$c = new \SQRT\QueryBuilder\Conditions();

$c->equal('one', 12)
  ->between('age', 10, 20)
  ->notLike('name', 'Peter%')
  ->in('status', array(1, 2, 3));

$q->where($c);

或者从查询中获取 Conditions 对象并直接操作

$c = $q->getWhere()
  ->in('status', array(1, 2, 3))
  ->between('age', 10, 20);

重要:如果在 SQL 表达式的某个部分需要多次指定同一列的条件,例如 id=1 OR id=2,则会发生变量命名冲突。

可以表示这种情况

    $q->getWhere()
      ->setJoinByOr();
      ->equal('one', 1)
      ->equal('one', 2)

调用 $q->asSQL() 将被正确处理,但在生成 prepared statement 时只会参与一个变量。

应更改逻辑,例如使用 $q->getWhere()->in('one', array(1, 2)),或者手动构建表达式并替换查询中的变量

    $q->getWhere()->expr('(one = :one OR one = :two)', array('one' => 1, 'two' => 2));

在这种情况下,在查询的不同部分中可以使用同一列的引用,因为变量名将是不同的,例如

    $qb->update('pages')->setEqual('id', 12)->where(array('id' => 10)); // UPDATE `pages` SET `id`=:set_id WHERE `id`=:where_id

更多示例可以在测试中查看:/test/unit/...