跳至主要内容

数据库

本章讲述了配置数据库连接、创建表、从扩展中运行数据库脚本以及手动构建数据库查询的基础知识。

注释

为了方便地将应用数据映射到数据库表,推荐使用Pagekit对象关系映射器(ORM),该工具在独立章节中有详细介绍。

配置

数据库凭证存储在 。Pagekit 支持 和 。config.phpmysqlsqlite

'database' => [
    'connections' => [
      'mysql' => [
        'host' => 'localhost',
        'user' => 'root',
        'password' => 'PASSWORD',
        'dbname' => 'DATABASE',
        'prefix' => 'PREFIX_',
      ],
    ],
  ],
  ...

数据库前缀的工作

所有表名都包含你 Pagekit 安装的前缀。要在后端动态寻址表,使用表名和符号作为前缀的占位符。按照惯例,你应该用扩展名开头表,例如扩展的选项表:@foobar@foobar_option

数据库实用性

您可以使用数据库服务工具来管理数据库模式(见以下示例)。

$util = $this['db']->getUtility();

检查是否存在表格

if ($util->tablesExist(['@table1', '@table2'])) {
  // tables exists
}

创建表格

使用时创建表,传递给回调的第一个参数将是一个实例。Utility::createTable($table, \Closure $callback)Doctrine\DBAL\Schema\Table

$util->createTable('@foobar_option', function($table) {
    $table->addColumn('id', 'integer', ['unsigned' => true, 'length' => 10, 'autoincrement' => true]);
    $table->addColumn('name', 'string', ['length' => 64, 'default' => '']);
    $table->addColumn('value', 'text');
    $table->addColumn('autoload', 'boolean', ['default' => false]);
    $table->setPrimaryKey(['id']);
    $table->addUniqueIndex(['name'], 'OPTION_NAME');
});

该对象是 的实例。你可以在官方教义文档中找到它的职业参考$table\Doctrine\DBAL\Schema\Table

在使用 S 创建列时,你可能还想查看 Doctrine 文档中的可用数据类型和可用列选项addColumn

制作桌子通常会在内侧的挂钩处完成。关于迁徙的更多信息请见下一节。installscripts.php

迁徙

数据库迁移在你扩展中的部分定义了。该scripts.php的完整示例可在 Hello 扩展中找到。记得把你的文件链接起来,这样它才会被执行:'updates'scripts.phpcomposer.json

    "extra": {
       "scripts": "scripts.php"
    },

在 中,你可以挂钩扩展生命周期的不同事件。scripts.php

事件钩子 描述
install 安装分机后会打电话。通常你会在这里创建表格。
enable 当分机在管理员区启用时才会打电话。
uninstall 分机被移除时才打电话。这里是整理你创建的所有东西的地方,比如把扩展里的所有表都删掉。
updates 扩展更新后运行任何代码。它期望有一个数组,每个键都是该代码应从的版本号。示例:
```
 /*
 * Runs all updates that are newer than the current version.
 *
 */
'updates' => [
    '0.5.0' => function ($app) {
        // executed when upgrading from a version older than 0.5.0
    },
    '0.9.0' => function ($app) {
        // executed when upgrading from a version older than 0.9.0
    },
],
```

修改现有表格

要修改现有表,请使用底层Doctrine DBAL中的现有工具。要向现有表格添加列,你可以在扩展的某个版本钩子中包含以下片段。updatesscripts.php

use Doctrine\DBAL\Schema\Comparator;

// ...

$util    = App::db()->getUtility();
$manager = $util->getSchemaManager();

if ($util->tableExists('@my_table')) {

    $tableOld = $util->getTable('@my_table');
    $table = clone $tableOld;

    $table->addColumn('title', 'string', ['length' => 255]);

    $comparator = new Comparator;
    $manager->alterTable($comparator->diffTable($tableOld, $table));
}

该对象是 的实例。你可以在官方教义文档中找到它的职业参考$table\Doctrine\DBAL\Schema\Table

查询

访问数据库有多种方式。Pagekit 提供了底层 MySQL 或 SQLite 的抽象功能,因此无需使用 PDO 或类似机制。

1. 查询构建器

QueryBuilder 提供了一种更便捷的查询创建方式。

示例:

$result = Application::db()->createQueryBuilder()->select('*')->from('@blog_post')->where('id = :id', ['id' => 1])->execute()->fetchAll();

获取一个查询构建对象

use Pagekit\Application;

// ...

$query = Application::db()->createQueryBuilder();

基本选择和条件

方法 描述
select($columns = ['*']) 创建并添加查询中的“select”。
from($table) 创建并设置查询的“from”。
where($condition, array $params = []) 创建并添加查询中的“where”。
orWhere($condition, array $params = []) 创建并添加“或在哪里”的查询。

示例:

// create query
$query = Application::db()->createQueryBuilder();

// fetch title and content of all blog posts that do not have any comments
$comments = $query
    ->select(['title', 'content'])
    ->from('@blog_post')
    ->where('comment_count = ?', [0])
    ->get();

查询执行

方法 描述
get($columns = ['*']) 执行查询并获取所有结果。
first($columns = ['*']) 执行查询并获得第一个结果。
count($column = '*') 执行查询并获得“计数”结果。
execute($columns = ['*']) 执行“select”查询。
update(array $values) 用给定的值执行“更新”查询。
delete() 执行“删除”查询。

聚合函数

方法 描述
min($column) 执行查询并获得“最小”结果。
max($column) 执行查询并获得“最大”结果。
sum($column) 执行查询并得到“和”结果。
avg($column) 执行查询并获得“平均值”结果。

示例:

// create query
$query = $query = Application::db()->createQueryBuilder();

// determine total number of blog comments
$count = $query
    ->select(['comment_count'])
    ->from('@blog_post')
    ->sum('comment_count');

高级查询方法

方法 描述
whereIn($column, $values, $not = false, $type = null) 创建并添加查询中的“where in”。
orWhereIn($column, $values, $not = false) 在查询中创建并添加“或在哪里”。
whereExists($callback, $not = false, $type = null) 创建并添加“where exists”(存在于哪里)查询。
orWhereExists(Closure $callback, $not = false) 在查询中创建并添加“或存在”。
whereInSet($column, $values, $not = false, $type = null) 创建并添加一个“where FIND_IN_SET”的查询。
groupBy($groupBy) 创建并添加“分组”功能。
having($having, $type = null) 创建并添加一个“haveing”代码。
orHaving($having) 创建并添加“或有”(or)“。
orderBy($sort, $order = null) 创建并添加“排序”代码。
offset($offset) 设置查询的偏移量,这意味着结果不会从第一个结果开始,而是从整数索引定义的结果开始。这对分页很有用。$offset
limit($limit) 设定查询的界限。 定义了返回的最大结果数。$limit
getSQL() 获取查询 SQL。

连接

方法 描述
join($table, $condition = null, $type = 'inner') 创建并添加“join”到查询中。
innerJoin($table, $condition = null) 创建并添加“内部连接”到查询中。
leftJoin($table, $condition = null) leftJoin($table, $condition = null)
rightJoin($table, $condition = null) 创建并添加“右连接”到查询中。

2. ORM 查询

当你在扩展中设置好 ORM 后,可以用你的模型类创建非常易读的查询。

示例:

$result = Role::where(['id <> ?'], [Role::ROLE_ANONYMOUS])->orderBy('priority')->get();

以下方法可用(定义在模型特征中)。

方法 描述
create($data = []) 从传入的数据数组创建该模型的新实例。
where($condition, array $params = []) 指定一个 where 条件。条件中的问号会被你输入的参数替换。返回一个对象,这样你可以串联方法调用以进行更具体的查询。示例:QueryBuilderUser::where(['name = ?'], ['peter'])
find($id) 通过标识符检索模型实体。
findAll() 检索该模型的所有实体。
save(array $data = []) 保存模型实体。
delete() 删除模型实体。
toArray(array $data = [], array $ignore = []) 以数组形式返回模型数据。输入一份要包含的属性键列表作为参数。传递一份将要排除的属性键项列表作为参数。$data$ignore
query() 返回一个实例,使用该类中的任何方法。本例提供了常规查询构建器中的所有方法,以及一些专门针对 ORM的额外方法。ORM\QueryBuilder

ORM 查询构建器:附加方法

方法 描述
get() 执行查询并获取所有结果。
first() 执行查询并获得第一个结果。
related($related) 设置那些将被加载的关系。
getRelations() 获取查询的全部关系。
getNestedRelations($relation) 获取查询的所有嵌套关系。

示例:

$comments = Comment::query()->related(['post' => function ($query) {
    return $query->related('comments');
}])->get();

3. 原始查询

查询数据库最简单的方式是向数据库发送原始查询。这基本上就是包裹在PDO上的一个外壳。

$result = Application::db()->executeQuery('select * from @blog_post')->fetchAll();
$result = Application::db()->executeQuery('select * from @blog_post WHERE id = :id', ['id' => 1])->fetchAll();

插入

在数据库中插入数据可以通过你能获取的数据库连接实例来实现(记得在文件顶部)。Application::db()use Pagekit\Application;

用这个方法insert($tableExpression, array $data, array $types = array())

示例:

Application::db()->insert('@system_page', [
    'title' => 'Home',
    'content' => "<p>Hello World</p>",
    'data' => '{"title":true}'
]);

使用 ORM 时,只需创建一个新的模型实例并调用该方法。save()

奥姆

通过 Pagekit 中的对象关系映射(ORM),你可以将模型类绑定到数据库表。虽然这比QueryBuilder需要多几行设置,但ORM大大减少了你手中的手动工作。使用ORM是管理应用数据存储和取回数据库的推荐方式。阅读更多关于Pagekit ORM的信息。