## Mix\Database\Connection::class
该类用于 MySQL 等关系型数据库的操作,语法简单明了,且具有独特的查询构造方式,可构造任何复杂的SQL。
>[success] 该类基于 PDO 扩展,[语句预处理](http://php.net/manual/zh/pdo.prepared-statements.php) 将帮助你免于SQL注入攻击
## 插入
~~~
$data = [
'name' => 'xiaoliu',
'content' => 'hahahaha',
];
$conn = $db->insert('post', $data);
$success = $conn->execute();
// 获得刚插入数据的id
$insertId = $conn->getLastInsertId();
~~~
## 批量插入
- INSERT INTO
~~~
$data = [
['name' => 'xiaoliu', 'content' => 'hahahaha'],
['name' => 'xiaoliu', 'content' => 'hahahaha'],
['name' => 'xiaoliu', 'content' => 'hahahaha'],
['name' => 'xiaoliu', 'content' => 'hahahaha'],
];
$conn = $db->batchInsert('post', $data);
$success = $conn->execute();
// 获得受影响的行数
$affectedRows = $conn->getRowCount();
~~~
- REPLACE INTO / INSERT IGNORE
> \>= v2.2.5
~~~
$db->batchInsert('post', $data, 'REPLACE INTO');
~~~
~~~
$db->batchInsert('post', $data, 'INSERT IGNORE');
~~~
## 更新
常规更新:
~~~
$set = [
'num' => 2,
'name' => 'xiaoliu2',
];
$where = [
['id', '=', 23],
];
$conn = $db->update('post', $set, $where);
$success = $conn->execute();
// 获得受影响的行数
$affectedRows = $conn->getRowCount();
~~~
>[success] 更新 / 删除支持 where 的各种 OR / AND / IN / NOT IN / BETWEEN / NOT BETWEEN 组合,与 QueryBuilder 使用方式相同,如:$where = [['id', '=', 1], ['or', ['id', '=', 2]]];
自增、自减:
~~~
$set = [
'num' => ['+', 2],
'num1' => ['-', 1],
];
$where = [
['id', '=', 23],
];
$conn = $db->update('post', $set, $where)
$success = $conn->execute();
// 获得受影响的行数
$affectedRows = $conn->getRowCount();
~~~
## 删除
~~~
$where = [
['id', '=', 23],
];
$conn = $db->delete('post', $where)
$success = $conn->execute();
// 获得受影响的行数
$affectedRows = $conn->getRowCount();
~~~
## 查询
- 执行原生 `SQL`
>[info] 请不要直接把参数拼接在 SQL 内执行,带参数的 SQL 请使用参数绑定。
~~~
$rows = $db->prepare("SELECT * FROM `post`")->queryAll();
~~~
- 参数绑定
普通参数绑定:
~~~
$sql = "SELECT * FROM `post` WHERE id = :id AND name = :name";
$rows = $db->prepare($sql)->bindParams([
'id' => 28,
'name' => 'xiaoliu',
])->queryOne();
~~~
占位符绑定:
~~~
$sql = "SELECT * FROM `post` WHERE id = ? AND name = ?";
$rows = $db->prepare($sql)->bindValues([28, 'xiaoliu'])->queryOne();
~~~
`IN`、`NOT IN` 数组参数绑定:
> `PDO` 扩展是不支持绑定数组参数的,所以 WHERE IN 都只能直接 `implode(', ',$array)` 拼接到 SQL 里面,MixPHP 帮你做了这一步,所以只需像下面这样使用。
~~~
$sql = "SELECT * FROM `post` WHERE id IN (:id)";
$rows = $db->prepare($sql)->bindParams([
'id' => [28, 29, 30],
])->queryAll();
~~~
## 查询组合
>[success] 可使用 QueryBuilder 替代该功能处理常用 SQL 的生成,而只在复杂 SQL 时使用该方法。
MixPHP 推崇原生 SQL 查询数据库,但由于原生 SQL 在动态 Where 时,做参数绑定会导致逻辑有些复杂,所以 MixPHP 封装了一个查询组合的功能,方便动态控制 Where 与 自动参数绑定。
用户可将整个 SQL 拆分为多个部分,每个部分可选择使用下例两个参数:
- `params` 字段内的值会绑定到对应的sql中。
- `if` 字段的值为 false 时,该段 SQL 会丢弃。
常用查询组合:
~~~
$rows = $db->prepare([
['SELECT * FROM `post`'],
['WHERE id = :id AND name = :name ORDER BY id ASC',
'params' => [
'id' => $this->id,
'name' => $this->name,
],
],
])->queryAll();
~~~
动态 Where 查询组合:
~~~
$rows = $db->prepare([
['SELECT * FROM `post` WHERE 1 = 1'],
['AND id = :id', 'params' => ['id' => $this->id], 'if' => isset($this->id)],
['AND name = :name', 'params' => ['name' => $this->name], 'if' => isset($this->name)],
['ORDER BY `post`.id ASC'],
])->queryAll();
~~~
>[info] WHERE 1 = 1 是一个小技巧,能避免没有 Where 时 SQL 错误的情况出现。
更复杂的查询组合,包含了:
- 动态 Join
- 动态 Where
- 分页
~~~
$rows = $db->prepare([
['SELECT *'],
['FROM `post`'],
[
'INNER JOIN `user` ON `user`.id = `post`.id',
'if' => isset($this->name),
],
['WHERE 1 = 1'],
[
'AND `post`.id = :id',
'params' => ['id' => $this->id],
'if' => isset($this->id),
],
[
'AND `user`.name = :name',
'params' => ['name' => $this->name],
'if' => isset($this->name),
],
['ORDER BY `post`.id ASC'],
['LIMIT :offset, :rows', 'params' => ['offset' => ($this->currentPage - 1) * $this->perPage, 'rows' => $this->perPage]],
])->queryAll();
~~~
## 使用 MySQL 函数、存储过程
```
$result = $db->prepare('select :uuid')->bindParams([
'uuid' => $db::raw('uuid()'),
])->queryAll();
$result = $db->batchInsert('test', [
['text' => 'aaa', 'created_at' => $db::raw('CURRENT_TIMESTAMP()'), 'uuid' => $db::raw('uuid()')],
['text' => 'bbb', 'created_at' => $db::raw('CURRENT_TIMESTAMP()'), 'uuid' => $db::raw('uuid()')],
])->execute();
```
## 查询返回结果集
返回多行,每行都是列名和值的关联数组。
> 没有结果返回空数组。
~~~
// 默认返回二维数组
$rows = $db->prepare("SELECT * FROM `post`")->queryAll();
// 指定返回对象数组
$rows = $db->prepare("SELECT * FROM `post`")->queryAll(\PDO::FETCH_OBJ);
~~~
返回一行 (第一行)。
> 没有结果返回 false。
~~~
// 默认返回数组
$row = $db->prepare("SELECT * FROM `post` WHERE id = 28")->queryOne();
// 指定返回对象
$row = $db->prepare("SELECT * FROM `post` WHERE id = 28")->queryOne(\PDO::FETCH_OBJ);
~~~
返回一列。
> 没有结果返回空数组。
~~~
// 第一列
$titles = $db->prepare("SELECT title FROM `post`")->queryColumn();
// 第二列
$titles = $db->prepare("SELECT * FROM `post`")->queryColumn(1);
~~~
返回一个标量值。
> 如果该查询没有结果则返回 false。
~~~
$count = $db->prepare("SELECT COUNT(*) FROM `post`")->queryScalar();
~~~
返回一个原生结果集 `PDOStatement` 对象。
> 通常在查询大量结果时,为了避免内存溢出时使用。
~~~
$statement = $db->prepare("SELECT * FROM `post`")->query();
while ($item = $statement->fetch()) {
var_dump($item);
}
~~~
## 返回 SQL 语句
`PDO` 扩展是无法获取最近执行的 SQL 的,所以这个功能是 MixPHP 通过参数构建出来的,这个在调试时是非常好用的功能。
~~~
$sql = $conn->getLastSql();
~~~
## 返回 SQL 日志
返回一个数组,包含 sql, bindings, time 三个字段。
~~~
$sql = $conn->getLastLog();
~~~
## 事务
手动事务:
~~~
$conn = $db->beginTransaction();
try {
$conn->insert('test', [
'text' => '测试测试',
])->execute();
$conn->commit();
} catch (\Exception $e) {
$conn->rollback();
throw $e;
}
~~~
自动事务:等同于上面的手动事务,抛出异常时自动回滚。
~~~
$db->transaction(function (\Mix\Database\Connection $conn) {
$conn->insert('test', [
'text' => '测试测试',
])->execute();
});
~~~
- 欢迎使用 MixPHP
- 安装说明
- 全栈开发
- 微服务开发
- Phar 开发
- 如何部署
- 独立部署
- Nginx
- Supervisord
- 新手教程
- 命令行常识
- 进程管理
- 热更新
- 全局变量
- 调试程序
- 入门须知
- 命名空间
- 自动加载
- 入口文件
- 增改应用
- 自动补全 IDE
- 核心功能
- 配置 (manifest.php)
- 依赖注入
- 事件调度
- 验证器
- 验证器定义
- 验证规则
- 静态调用
- 日志 Monolog
- 缓存
- 协程
- 什么是协程
- 开启协程
- Runtime
- 简介
- 创建协程 xgo + Channel
- 创建协程 xgo + WaitGroup
- xgo
- xdefer
- Channel
- WaitGroup
- Timer + Ticker
- Signal
- Select
- Context
- WorkerPool
- 数据库
- Database
- Database
- Connection
- QueryBuilder
- ExecutedEvent
- Redis
- Redis
- Connection
- CalledEvent
- 命令行
- 简介
- Application
- 创建命令
- 命令参数
- 打印与颜色
- 守护进程
- 后台运行
- Web/API 应用
- 简介
- 编写一个接口
- 服务器
- 路由 FastRoute
- 中间件
- 请求
- 响应
- 文件上传
- 控制器
- 视图
- Auth
- Session
- Guzzle
- HTTP 404/500
- 安全建议
- WebSocket 应用
- 简介
- 服务器
- 客户端
- Client
- JavaScript
- Swoole
- nginx代理
- 60s无消息断线
- Micro 微服务
- 简介
- 编写一个微服务
- Mix Micro
- Go Micro
- gRPC
- JSON-RPC
- 服务注册
- 配置中心
- 熔断与降级
- 调用链追踪
- 服务限流
- Sync Invoke 同步调用
- 简介
- 服务器
- 客户端
- TCP 应用
- 简介
- 服务器
- 客户端
- Telnet
- PHP
- Swoole
- UDP 应用
- 简介
- 服务器
- 客户端
- NC
- Swoole
- 第三方接入
- EasyWeChat
- Sentry
- Doctrine Cache
- 常见问题
- 如何利用 CPU 多核
- 连接多个数据库
- 如何设置跨域
- form-data 上传文件失败
- 输出大于 2M 的文件失败