数据库
本章讲述了配置数据库连接、创建表、从扩展中运行数据库脚本以及手动构建数据库查询的基础知识。
为了方便地将应用数据映射到数据库表,推荐使用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的信息。