pixie, 面向PHP的数据库查询生成器,框架不可知,轻量级和具有表现力

分享于 

24分钟阅读

GitHub

  繁體 雙語
A query builder for PHP, framework agnostic, lightweight and expressive.
  • 源代码名称:pixie
  • 源代码网址:http://www.github.com/usmanhalalit/pixie
  • pixie源代码文档
  • pixie源代码下载
  • Git URL:
    git://www.github.com/usmanhalalit/pixie.git
    Git Clone代码到本地:
    git clone http://www.github.com/usmanhalalit/pixie
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/usmanhalalit/pixie
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    查询生成器 Build Status

    一种轻量级。表达式。框架无关的PHP查询生成器它也可以被称为数据库抽象。 Pixie支持 MySQL。SQLite和 PostgreSQL,它使用统一的API处理查询消毒。表前缀和许多其他事情。 至少需要 PHP 5.3。

    它具有一些高级功能,例如:

    • 查询事件
    • 嵌套条件
    • 子查询
    • 嵌套查询
    • 多个数据库连接。

    语法与 Laravel builder的查询非常相似。

    示例

    // Make sure you have Composer's autoload file includedrequire'vendor/autoload.php';// Create a connection, once only.$config=array('driver'=>'mysql', // Db driver'host'=>'localhost','database'=>'your-database','username'=>'root','password'=>'your-password','charset'=>'utf8', // Optional'collation'=>'utf8_unicode_ci', // Optional'prefix'=>'cb_', // Table prefix, optional'options'=>array( // PDO constructor options, optionalPDO::ATTR_TIMEOUT=>5,PDO::ATTR_EMULATE_PREPARES=>false, ), );newPixieConnection('mysql', $config, 'QB');

    简单查询:

    下面的查询返回 id = 3的行,如果没有行,则返回 null。

    $row=QB::table('my_table')->find(3);

    完整查询:

    $query=QB::table('my_table')->where('name', '=', 'Sana');// Get result$query->get();

    查询事件:

    在下面的代码之后,每次在 users 表上进行选择查询时,它将添加这个条件,这样被禁止的用户就不能访问。

    QB::registerEvent('before-select', 'users', function($qb){$qb->where('status', '!=', 'banned');});

    下面有许多高级的选项。 已经售出我们安装。

    安装

    Pixie使用 Composer 来简化事情。

    了解使用 Composer 并将它的添加到需要的节( 在你的composer.json 中) 中:

    
    "usmanhalalit/pixie":"2.*@dev"
    
    
    
    

    然后运行:

     
    composer update
    
    
    
     

    Packagist上的库。

    完全使用 API

    目录

    拨号连接

    Pixie支持三个数据库驱动程序,MySQL,SQLite和 PostgreSQL。 你可以在创建新连接时指定连接过程中的驱动程序和关联的配置。 还可以创建多个连接,但一次只能使用别名作为一个连接。

    // Make sure you have Composer's autoload file includedrequire'vendor/autoload.php';$config=array('driver'=>'mysql', // Db driver'host'=>'localhost','database'=>'your-database','username'=>'root','password'=>'your-password','charset'=>'utf8', // Optional'collation'=>'utf8_unicode_ci', // Optional'prefix'=>'cb_', // Table prefix, optional );newPixieConnection('mysql', $config, 'QB');// Run query$query=QB::table('my_table')->where('name', '=', 'Sana');

    别名

    创建连接时:

    newPixieConnection('mysql', $config, 'MyAlias');

    如果你想要使用( 像 MyAlias::table(...) ),那么你可以使用 MyAlias,或者你可以跳过它,如果不需要别名,可以跳过它。 别名使你能够轻松访问应用程序中的QueryBuilder类。

    当不用别名时,可以单独实例化QueryBuilder处理程序,这有助于依赖注入和测试。

    $connection=newPixieConnection('mysql', $config);$qb=newPixieQueryBuilderQueryBuilderHandler($connection);$query=$qb->table('my_table')->where('name', '=', 'Sana');var_dump($query->get());

    $connection 是可选的,如果没有给出,它将始终与第一个连接相关联,但是当你有多个数据库连接时。

    SQLite和PostgreSQL配置示例

    newPixieConnection('sqlite', array('driver'=>'sqlite','database'=>'your-file.sqlite','prefix'=>'cb_', ), 'QB');
    newPixieConnection('pgsql', array('driver'=>'pgsql','host'=>'localhost','database'=>'your-database','username'=>'postgres','password'=>'your-password','charset'=>'utf8','prefix'=>'cb_','schema'=>'public', ), 'QB');

    查询

    你必须在每次查询前使用方法 ,除原始 query() 要从多个表中选择,只需传递一个 array。

    QB::table(array('mytable1', 'mytable2'));

    容易

    下面的查询返回( 首) 行,其中 id = 3,如果没有行,则返回 null。

    $row=QB::table('my_table')->find(3);

    像这样访问你的行,echo $row->name。 如果字段 NAME 不是 id,那么将字段 NAME 作为第二个参数传递 QB::table('my_table')->find(3, 'person_id');

    下面的查询返回 NAME ='Sana'的所有行,如果没有行,则返回 null。

    $result=QB::table('my_table')->findAll('name', 'Sana');

    选择

    $query=QB::table('my_table')->select('*');
    多个选择
    ->select(array('mytable.myfield1', 'mytable.myfield2', 'another_table.myfield3'));

    多次使用select方法 select('a')->select('b') 也将选择 ab。 如果你想做条件选择( 在 PHP if 中),则会很有用。

    SELECT DISTINCT
    ->selectDistinct(array('mytable.myfield1', 'mytable.myfield2'));

    返回 array。

    $query=QB::table('my_table')->where('name', '=', 'Sana');$result=$query->get();

    你可以像这样循环:

    foreach ($resultas$row) {echo$row->name;}
    获得第一行
    $query=QB::table('my_table')->where('name', '=', 'Sana');$row=$query->first();

    返回第一行,如果没有记录,则返回 null。 使用这里方法还可以确保记录是否存在。 像 echo $row->name 这样访问。

    获取行计数
    $query=QB::table('my_table')->where('name', '=', 'Sana');$query->count();

    基本语法是 (fieldname, operator, value),如果给出两个参数,则假定 = 运算符为。 所以 where('name','usman')where('name','=','usman') 是一样的。

    QB::table('my_table')->where('name', '=', 'usman')->whereNot('age', '>', 25)->orWhere('type', '=', 'admin')->orWhereNot('description', 'LIKE', '%query%') ;
    QB::table('my_table')->whereIn('name', array('usman', 'sana'))->orWhereIn('name', array('heera', 'dalim')) ;QB::table('my_table')->whereNotIn('name', array('heera', 'dalim'))->orWhereNotIn('name', array('usman', 'sana')) ;
    QB::table('my_table')->whereBetween('id', 10, 100)->orWhereBetween('status', 5, 8);
    Null
    QB::table('my_table')->whereNull('modified')->orWhereNull('field2')->whereNotNull('field3')->orWhereNotNull('field4');
    分组在

    有时查询变得复杂,在这里你需要分组标准,例如 WHERE age = 10 and (name like '%usman%' or description LIKE '%usman%')

    Pixie允许你这样做,你可以根据需要嵌套任意数量的闭包,如下所示。

    QB::table('my_table')->where('my_table.age', 10)->where(function($q) {$q->where('name', 'LIKE', '%usman%');// You can provide a closure on these wheres too, to nest further.$q->orWhere('description', 'LIKE', '%usman%'); });

    GROUP BY 和 ORDER BY

    $query=QB::table('my_table')->groupBy('age')->orderBy('created_at', 'ASC');
    多个 GROUP BY
    ->groupBy(array('mytable.myfield1', 'mytable.myfield2', 'another_table.myfield3'));->orderBy(array('mytable.myfield1', 'mytable.myfield2', 'another_table.myfield3'));

    使用 groupBy() 或者 orderBy() 方法多次 groupBy('a')->groupBy('b') 也将是 GROUP BY 第一个 a,而不是 b。 如果你希望进行条件分组( 在 PHP if 中),则会很有用。 同样适用于 orderBy()

    ->having('total_count', '>', 2)->orHaving('type', '=', 'admin');

    极限和偏移

    ->limit(30);->offset(10);

    连接

    QB::table('my_table')->join('another_table', 'another_table.person_id', '=', 'my_table.id')

    可用的方法,

    • join() 或者 innerJoin
    • leftJoin ( )
    • rightJoin ( )

    如果你需要 FULL OUTER Join 或者其他 Join,只要将它作为 join 方法的5th 参数传递。

    ->join('another_table', 'another_table.person_id', '=', 'my_table.id', 'FULL OUTER')
    多个 Join 标准

    如果需要一个以上的标准来 Join,然后将闭包作为第二个参数传递。

    ->join('another_table', function($table) {$table->on('another_table.person_id', '=', 'my_table.id');$table->on('another_table.person_id2', '=', 'my_table.id2');$table->orOn('another_table.age', '>', QB::raw(1)); })

    原始查询

    如果需要,可以始终使用原始查询,

    $query=QB::query('select * from cb_my_table where age = 12');var_dump($query->get());

    你还可以传递绑定

    QB::query('select * from cb_my_table where age =? and name =?', array(10, 'usman'));
    原始表达式

    当用 raw() 方法包装表达式时,Pixie不会尝试清除这些。

    QB::table('my_table')->select(QB::raw('count(cb_my_table.id) as tot'))->where('value', '=', 'Ifrah')->where(QB::raw('DATE(?)', 'now'))

    注意:通过方法运行的查询直到通过绑定传递所有值后才会被清除。 通过 raw() 方法运行的查询也不会被清除,你必须自己做。 当然,这些并不添加表前缀,但是你可以使用 addTablePrefix() 方法。

    插入

    $data=array('name'=>'Sana','description'=>'Blah');$insertId=QB::table('my_table')->insert($data);

    insert() 方法返回插入标识。

    批量插入
    $data=array(array('name'=>'Sana','description'=>'Blah' ),array('name'=>'Usman','description'=>'Blah' ),);$insertIds=QB::table('my_table')->insert($data);

    在批插入时,它将返回一个插入id的array。

    插入重复密钥语句
    $data=array('name'=>'Sana','counter'=>1);$dataUpdate=array('name'=>'Sana','counter'=>2);$insertId=QB::table('my_table')->onDuplicateKeyUpdate($dataUpdate)->insert($data);

    更新

    $data=array('name'=>'Sana','description'=>'Blah');QB::table('my_table')->where('id', 5)->update($data);

    将 NAME 字段更新为Sana和说明字段,其中 id = 5.

    删除

    QB::table('my_table')->where('id', '>', 5)->delete();

    将删除id为 GREATER的所有行,而不是 5.

    事务

    Pixie能够运行数据库"事务处理",在该数据库中,所有数据库更改都不会被保存,直到提交。 这样,如果出现错误或者不同的情况,则数据库更改不会保存,也不会做出任何更改。

    以下是基本事务:

    QB::transaction(function ($qb) {$qb->table('my_table')->insert(array('name'=>'Test','url'=>'example.com' ));$qb->table('my_table')->insert(array('name'=>'Test2','url'=>'example.com' ));});

    如果这导致了任何错误( 例如重复 NAME 或者其他此类错误),数据库中都不会显示数据集。 如果没有,将成功保存更改。

    如果你希望手动提交或者回滚更改,则可以使用 commit()rollback() 方法:

    QB::transaction(function ($qb) {$qb->table('my_table')->insert(array(/* data... */));$qb->commit(); // to commit the changes (data would be saved)$qb->rollback(); // to rollback the changes (data would be rejected)});

    生成查询

    有时你可能需要获取查询字符串,它可能。

    $query=QB::table('my_table')->where('id', '=', 3);$queryObj=$query->getQuery();

    getQuery() 将返回一个查询对象,从这里可以得到 sql。绑定或者原始 sql。

    $queryObj->getSql();// Returns: SELECT * FROM my_table where `id` =?
    $queryObj->getBindings();// Returns: array(3)
    $queryObj->getRawSql();// Returns: SELECT * FROM my_table where `id` = 3

    子查询和嵌套查询

    很少,但你可能需要执行子查询或者嵌套查询。 Pixie足够强大,可以为你做这个。 你可以创建不同的查询对象并使用 QB::subQuery() 方法。

    $subQuery=QB::table('person_details')->select('details')->where('person_id', '=', 3);$query=QB::table('my_table')->select('my_table.*')->select(QB::subQuery($subQuery, 'table_alias1'));$nestedQuery=QB::table(QB::subQuery($query, 'table_alias2'))->select('*');$nestedQuery->get();

    这将产生这样的查询:

    
    SELECT * FROM (SELECT `cb_my_table`.*, (SELECT `details` FROM `cb_person_details` WHERE `person_id` = 3) as table_alias1 FROM `cb_my_table`) as table_alias2
    
    
    
    

    注意:Pixie不使用子查询和嵌套查询绑定。 它使用 quote() 方法的引用值。

    获取PDO实例

    如果你需要获得PDO实例,那么你可以这样做。

    QB::pdo();

    将结果作为指定类的对象

    简单地调用 asObject的查询方法。

    QB::table('my_table')->asObject('SomeClass', array('ctor', 'args'))->first();

    此外,你可以通过调用 setFetchMode 方法微调获取模式。

    QB::table('my_table')->setFetchMode(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE)->get();

    查询事件

    Pixie提供强大的查询事件来增强你的应用程序。 这些事件类似于数据库触发器,可以在发生事件时执行某些操作,例如可以钩子表的after-delete 事件并从另一个表中删除相关数据。

    可用事件
    • 选择前
    • 选择后
    • 插入前
    • 插入后
    • 更新前
    • 更新后
    • 删除前
    • 删除后
    注册事件
    QB::registerEvent('before-select', 'users', function($qb){$qb->where('status', '!=', 'banned');});

    现在每次在 users 表上发生选择查询时,它都会添加这个标准,因这里禁止用户获取访问权限。

    语法是 registerEvent('event type', 'table name', action in a closure)

    如果你希望在将任何表查询为时执行事件,请将 ':any' 作为表名提供。

    其他示例:

    将数据插入 my_table 后,详细信息将插入到另一个表中

    QB::registerEvent('after-insert', 'my_table', function($queryBuilder, $insertId){$data=array('person_id'=>$insertId, 'details'=>'Meh', 'age'=>5);$queryBuilder->table('person_details')->insert($data);});

    当数据插入 person_details 表中时,设置时间戳字段 created_at,这样我们就不必在任何地方指定它:

    QB::registerEvent('after-insert', 'person_details', function($queryBuilder, $insertId){$queryBuilder->table('person_details')->where('id', $insertId)->update(array('created_at'=>date('Y-m-d H:i:s')));});

    my_table 删除后删除关系:

    QB::registerEvent('after-delete', 'my_table', function($queryBuilder, $queryObject){$bindings=$queryObject->getBindings();$queryBuilder->table('person_details')->where('person_id', $binding[0])->delete();});

    Pixie作为闭包的第一个参数传递查询生成器的当前实例,因此你可以使用这个对象构建查询,你可以像通常的查询生成器( QB ) 那样做。

    如果从查询处理程序返回非 null,则值将是执行的结果,并且数据库不会真正被查询到。

    只有在 after-* 事件上,你才能获得三个参数: 第一个是查询生成器,第三个是执行时间的,而第二个的值为:

    • after-select 上,获得从 select 获得的results
    • after-insert 上,可以获得插入 id ( 在批插入时为 ids )
    • after-delete 上,可以获得查询对象 ( 与从 getQuery() 获得的内容相同),你可以从它获取SQL和绑定。
    • after-update 上,你得到了查询对象( 如)。
    删除事件
    QB::removeEvent('event-name', 'table-name');
    一些用例

    下面是查询事件非常有用的一些情况:

    • 限制禁止用户。
    • 仅获取 deleted = 0 记录。
    • 实现所有查询的缓存。
    • 在每个条目之后触发用户通知。
    • 删除删除查询后删除关系数据。
    • 插入查询后插入关系数据。
    • 在每次更新查询后保留修改记录。
    • 添加/编辑created_at并在每个条目后更新_at数据。
    注释
    • 查询事件按连接设置,因此多数据库连接不会创建任何问题,并且创建新的查询生成器实例将保留你的事件。
    • table_a的事件插入到 table_b 之后,你可以将事件插入到中,现在你可以将另一个事件注册到 table_b,该事件将。
    • 当然,查询事件不能与原始查询一起使用。

    如果你发现任何错误,请编辑并发送请求请求。

    © 2016 穆罕默德 Usman。 许可许可许可许可。


    数据    EXP  PHP  构建  Light  
    相关文章