phpixie/database

PHPixie 数据库库

3.11.1 2020-02-24 23:06 UTC

README

支持MySQL、PostgreSQL、SQLite和MongoDB的通用查询接口

Build Status Test Coverage Code Climate HHVM Status

Author Source Code Software License Total Downloads

初始化

$slice = new \PHPixie\Slice();
$database = new \PHPixie\Database($slice->arrayData(array(
    'default' => array(
        'driver' => 'pdo',
        'connection' => 'sqlite::memory:'
    )
)));

如果您使用PHPixie框架,数据库组件将自动初始化。通过 $frameworkBuilder->components()->database() 访问它,并在 /config/database.php 文件中进行配置。

return array(
    //You can define multiple connections
    //each with a different name
    'default' => array(
        'driver'     => 'pdo',
        
        //MySQL
        'connection' => 'mysql:host=localhost;dbname=phpixie',
        
        //or SQLite
        'connection' => 'sqlite:/some/file',
        
        //or Postgres
        'connection' => 'pgsql:dbname=exampledb',
        
        'user'       => 'root',
        'password'   => 'password'
    ),
    
    'other' => array(
        //connecting to MongoDD
        'driver'   => 'mongo',
        'database' => 'phpixie',
        'user'     => 'pixie',
        'password' => 'password'
    )
);

查询

在PHPixie中查询关系数据库和MongoDB集合非常相似。我们先来看关系数据库

$connection = $database->get('default');

// SELECT * FROM `posts` WHERE `status`='published'
// LIMIT 5 OFFSET 1
$query = $connection->selectQuery();
$posts = $query
    ->table('posts')
    ->where('status', 'Published')
    ->limit(5)
    ->offset(1)
    ->execute();
    
// Specifying fields
$query->fields(array('id'));

// You can remove limit, offset
// specified fields, etc from the query
// using clearSomething()
$query->clearFields();

//And get it using getSomething()
$query->getFields();

//Using OR and XOR logic
$query
    ->where('status', 'published')
    ->orWhereNot('status', 'deleted')
    ->xorWhere('id', 5);
    
//Shorthand functions
$query
    ->and('status', 'published')
    ->orNot('status', 'deleted')
    ->xor('id', 5);

// WHERE `status` = 'published'
// OR NOT (`id` = 4 AND `views` = 5)
$query
    ->where('status', 'published')
    ->startOrNotGroup()
        ->where('id', 4)
        ->and('views', 4)
    ->endGroup();

// Less verbose syntax
$query
    ->where('status', 'published')
    ->or(function(query) {
        $query
            ->where('id', 4)
            ->and('views', 4);
    });
    
// More verbose syntax
// Useful for programmatic filters
$query
    ->addOperatorCondition(
        $logic    = 'and',
        $negate   = false,
        $field    = 'status',
        $operator = '=',
        array('published')
    )
    ->startConditionGroup(
        $logic    = 'and',
        $negate   = false
    );

使用 andorxor 添加条件到最后使用的条件类型。因此,在 where() 之后调用 or 将与 orWhere() 相同,而使用它之后 having() 将被视为 orHaving()

运算符

// So far we only compared fields with values
// But there are other operators available

// >, < , >=, <=, '!='
$query->where('views', '>', 5);

// comparies fields to other fields
// can be done by adding an '*'
$query->where('votes', '>=*', 'votesRequired');

// Between
$query->where('votes', 'between', 5, 6);

// In
$query->where('votes', 'in', array(5, 6));

// Like
$query->where('name', 'like', 'Welcome%');

// Regexp
$query->where('name', 'regexp', '.*');

// SQL expression
$expression = $database->sqlExpression('LOWER(?)', array('text'));
$query->where('title', $expression);

// You can also use it for fields
// SELECT COUNT(1) as `count`
$expression = $database->sqlExpression('COUNT(1)');
$query->fields(array(
    'count' => $expression
));

表、子查询和JOIN

// When specofying a table
// you can also define an alias for it
$query->table('posts', 'p');

// INNER JOIN `categories`
$query->join('categories')

// LEFT JOIN `categories` AS `c`
$query->join('categories', 'c', 'left')

$query
    ->on('p.categoryId', 'c.categoryId');
    
// The on() conditions can be used in
// the same way as where(), and apply
// to the last join() statement
$query
    ->join('categories', 'c', 'left')
        ->on('p.categoryId', 'c.id')
        ->or('p.parentCategoryId', 'c.id')
    ->join('authors')
        ->on('p.authorId', 'authors.id');
        
// You can use subqueries as tables,
// but you must supply the alias parameter

$query->join($subqeury, 'c', 'left')

//UNIONs
$query->union($subquery, $all = true);

聚合

定义完字段后,您可以使用 HAVING,就像使用 WHERE 一样;

$query
    ->fields(array(
        'count' => $database->sqlExpression('COUNT(1)');
    ))
    ->having('count', '>', 5)
    ->or('count', '<', 2);

其他类型的查询

// Delete syntax is very similar to select
// except it doesn't support HAVING syntax
$connection->deleteQuery()
    ->where('id', 5)
    ->execute();

// Count query is a shorthand that returns the count
// of matched items
$count = $connection->countQuery()
    ->where('id', '>', 5)
    ->execute();

// Inserting
$insertQuery = $connection->insertQuery();
$insertQuery->data(array(
    'id'    => 1,
    'title' => 'Hello'
))->execute();

// Insert multiple rows
$insertQuery->batchData(
    array('id', 'title'),
    array(
        array(1, 'Hello'),
        array(2, 'World'),
    )
)->execute();

// Getting insert id
$connection->insertId();

// Updating
$updateQuery = $connection->updateQuery();
$updateQuery
    ->set('name', 'Hello')
    ->where('id', 4)
    ->execute();

// increment values
$updateQuery
    ->increment(array(
        'views' => 1
    ))
    ->execute();

占位符

查询占位符是另一种简化编程查询构建的方法。您可以先创建一个占位符,然后稍后再用实际条件替换它。以下是一个示例

$query
    ->where('status', 'published')
    ->startOrGroup();

// Add placeholder inside the OR goup
$placeholder = $query->addPlaceholder(
    $logic  = 'and',
    $negate = false,
    $allowEmpty = false
);

$query
        ->and('views', '>', 5);
    ->endGroup();

// so far this results in
// WHERE `status` = 'published'
// OR (<placeholder> AND `views` > 5)

// Now we can replace the placeholder by
// adding conditions to it
$placeholder->where('votes', '>', 5);

事务

事务的基本用法是在发生异常时回滚它们,然后重新抛出异常

$database->beginTransaction();
// ...
try {
    // ...
    $database->commitTransaction();
} catch(\Exception $e) {
    $database->rollbackTransaction();
    throw $e;
}

PHPixie 还支持事务保存点,可用于实现一些更高级的行为

$name = $database->savepointTransaction();
$database->rollbackTransactionTo($name);

MongoDB

查询MongoDB与查询SQL数据库非常相似。当然,您不能使用如 JOINHAVING 语句、事务等关系方法。但您将获得一些额外的功能

$posts = $query
    ->collection('posts')
    // subdocument conditions
    ->where('author.name', 'Dracony')
    ->limit(1)
    ->offset(1)
    ->execute();

$connection->updateQuery()
    ->collection('posts')
    ->set('done', true)
    ->unset(array('started', 'inProgress'))
    ->execute();
    
$connection->insertQuery()
    ->collection('posts')
    ->batchData(array(
        array(
            'name' => 'Trixie'
        ),
        array(
            'name' => 'Stella'
        )
    ))
    ->execute();

使用子文档组可以更轻松地查询子文档

//setting conditions for subdocuments
$query
    ->startOrNotSubdocumentGroup('author')
        ->where('name', 'Dracony')
    ->endGroup();
    
//setting conditions for subarray items
$query
    ->startOrNotSubarrayItemGroup('authors')
        ->where('name', 'Dracony')
    ->endGroup();