tp5源码分析之数据库查询
1 查询对象
查询对象(Query)实现基本的查询操作
与模型不同的是,查询对象是在数据库的整体上进行操作,所以需要指定数据库表
模型针对的数据库中的某个数据表的操作。
2 查询操作
2-1 增删改查
$query->insert()
public function insert(array $data, $replace = false, $getLastInsID = false, $sequence = null)
{
// 分析查询表达式
$options = $this->parseExpress();
// 生成SQL语句
$sql = $this->builder()->insert($data, $options, $replace);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
}
// 执行操作
$result = $this->execute($sql, $bind);
if ($getLastInsID) {
$sequence = $sequence ?: (isset($options["sequence"]) ? $options["sequence"] : null);
return $this->getLastInsID($sequence);
}
return $result;
}
$query->insertAll()
public function insertAll(array $dataSet)
{
// 分析查询表达式
$options = $this->parseExpress();
if (!is_array(reset($dataSet))) {
return false;
}
// 生成SQL语句
$sql = $this->builder()->insertAll($dataSet, $options);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
} else {
// 执行操作
return $this->execute($sql, $bind);
}
}
$query->selectInsert()
public function selectInsert($fields, $table)
{
// 分析查询表达式
$options = $this->parseExpress();
// 生成SQL语句
$table = $this->parseSqlTable($table);
$sql = $this->builder()->selectInsert($fields, $table, $options);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
} else {
// 执行操作
return $this->execute($sql, $bind);
}
}
$query->select()
public function select($data = null)
{
if ($data instanceof Query) {
return $data->select();
} elseif ($data instanceof Closure) {
call_user_func_array($data, [ & $this]);
$data = null;
}
// 分析查询表达式
$options = $this->parseExpress();
if (false === $data) {
// 用于子查询 不查询只返回SQL
$options["fetch_sql"] = true;
} elseif (!is_null($data)) {
// 主键条件分析
$this->parsePkWhere($data, $options);
}
$resultSet = false;
if (empty($options["fetch_sql"]) && !empty($options["cache"])) {
// 判断查询缓存
$cache = $options["cache"];
unset($options["cache"]);
$key = is_string($cache["key"]) ? $cache["key"] : md5(serialize($options));
$resultSet = Cache::get($key);
}
if (!$resultSet) {
// 生成查询SQL
$sql = $this->builder()->select($options);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
}
// 执行查询操作
$resultSet = $this->query($sql, $bind, $options["master"], $options["fetch_class"]);
if ($resultSet instanceof PDOStatement) {
// 返回PDOStatement对象
return $resultSet;
}
if (isset($cache)) {
// 缓存数据集
if (isset($cache["tag"])) {
Cache::tag($cache["tag"])->set($key, $resultSet, $cache["expire"]);
} else {
Cache::set($key, $resultSet, $cache["expire"]);
}
}
}
// 返回结果处理
if (count($resultSet) > 0) {
// 数据列表读取后的处理
if (!empty($this->model)) {
// 生成模型对象
$model = $this->model;
foreach ($resultSet as $key => $result) {
/** @var Model $result */
$result = new $model($result);
$result->isUpdate(true);
// 关联查询
if (!empty($options["relation"])) {
$result->relationQuery($options["relation"]);
}
$resultSet[$key] = $result;
}
if (!empty($options["with"]) && $result instanceof Model) {
// 预载入
$resultSet = $result->eagerlyResultSet($resultSet, $options["with"], is_object($resultSet) ? get_class($resultSet) : "");
}
}
} elseif (!empty($options["fail"])) {
$this->throwNotFound($options);
}
return $resultSet;
}
$query->find()
public function find($data = null)
{
if ($data instanceof Query) {
return $data->find();
} elseif ($data instanceof Closure) {
call_user_func_array($data, [ & $this]);
$data = null;
}
// 分析查询表达式
$options = $this->parseExpress();
if (!is_null($data)) {
// AR模式分析主键条件
$this->parsePkWhere($data, $options);
}
$options["limit"] = 1;
$result = false;
if (empty($options["fetch_sql"]) && !empty($options["cache"])) {
// 判断查询缓存
$cache = $options["cache"];
if (true === $cache["key"] && !is_null($data) && !is_array($data)) {
$key = "think:" . $options["table"] . "|" . $data;
} else {
$key = is_string($cache["key"]) ? $cache["key"] : md5(serialize($options));
}
$result = Cache::get($key);
}
if (!$result) {
// 生成查询SQL
$sql = $this->builder()->select($options);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
}
// 执行查询
$result = $this->query($sql, $bind, $options["master"], $options["fetch_class"]);
if ($result instanceof PDOStatement) {
// 返回PDOStatement对象
return $result;
}
if (isset($cache)) {
// 缓存数据
if (isset($cache["tag"])) {
Cache::tag($cache["tag"])->set($key, $result, $cache["expire"]);
} else {
Cache::set($key, $result, $cache["expire"]);
}
}
}
// 数据处理
if (!empty($result[0])) {
$data = $result[0];
if (!empty($this->model)) {
// 返回模型对象
$model = $this->model;
$data = new $model($data);
$data->isUpdate(true, isset($options["where"]["AND"]) ? $options["where"]["AND"] : null);
if ($this->allowField) {
$data->allowField($this->allowField);
}
// 关联查询
if (!empty($options["relation"])) {
$data->relationQuery($options["relation"]);
}
if (!empty($options["with"])) {
// 预载入
$data->eagerlyResult($data, $options["with"], is_object($result) ? get_class($result) : "");
}
}
} elseif (!empty($options["fail"])) {
$this->throwNotFound($options);
} else {
$data = null;
}
return $data;
}
$query->update()
public function update(array $data)
{
$options = $this->parseExpress();
$pk = $this->getPk($options);
if (isset($options["cache"]) && is_string($options["cache"])) {
$key = $options["cache"];
}
if (empty($options["where"])) {
// 如果存在主键数据 则自动作为更新条件
if (is_string($pk) && isset($data[$pk])) {
$where[$pk] = $data[$pk];
if (!isset($key)) {
$key = "think:" . $options["table"] . "|" . $data[$pk];
}
unset($data[$pk]);
} elseif (is_array($pk)) {
// 增加复合主键支持
foreach ($pk as $field) {
if (isset($data[$field])) {
$where[$field] = $data[$field];
} else {
// 如果缺少复合主键数据则不执行
throw new Exception("miss complex primary data");
}
unset($data[$field]);
}
}
if (!isset($where)) {
// 如果没有任何更新条件则不执行
throw new Exception("miss update condition");
} else {
$options["where"]["AND"] = $where;
}
} elseif (is_string($pk) && isset($options["where"]["AND"][$pk]) && is_scalar($options["where"]["AND"][$pk])) {
$key = "think:" . $options["table"] . "|" . $options["where"]["AND"][$pk];
}
// 生成UPDATE SQL语句
$sql = $this->builder()->update($data, $options);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
} else {
// 检测缓存
if (isset($key) && Cache::get($key)) {
// 删除缓存
Cache::rm($key);
}
// 执行操作
return "" == $sql ? 0 : $this->execute($sql, $bind);
}
}
$query->delete()
public function delete($data = null)
{
// 分析查询表达式
$options = $this->parseExpress();
if (isset($options["cache"]) && is_string($options["cache"])) {
$key = $options["cache"];
}
if (!is_null($data) && true !== $data) {
if (!isset($key) && !is_array($data)) {
// 缓存标识
$key = "think:" . $options["table"] . "|" . $data;
}
// AR模式分析主键条件
$this->parsePkWhere($data, $options);
}
if (true !== $data && empty($options["where"])) {
// 如果条件为空 不进行删除操作 除非设置 1=1
throw new Exception("delete without condition");
}
// 生成删除SQL语句
$sql = $this->builder()->delete($options);
// 获取参数绑定
$bind = $this->getBind();
if ($options["fetch_sql"]) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
}
// 检测缓存
if (isset($key) && Cache::get($key)) {
// 删除缓存
Cache::rm($key);
}
// 执行操作
return $this->execute($sql, $bind);
}
2-2 事务操作
$query->startTrans()
启动事务
public function startTrans()
{
$this->connection->startTrans();
}
$query->commit()
提交事务
public function commit()
{
$this->connection->commit();
}
$query->transaction()
执行事务
public function transaction($callback)
{
return $this->connection->transaction($callback);
}
$query->rollback()
回滚事务
public function rollback()
{
$this->connection->rollback();
}
2-3 sql语句操作
$query->query()
调用连接器的静态query方法
public function query($sql, $bind = [], $master = false, $class = false)
{
return $this->connection->query($sql, $bind, $master, $class);
}
$query->execute()
调用连接器的静态query方法
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: php: 打印log日志,存储数据到log文档 实例
- 下一篇: tp基本的增删改查的操作demo
copyright © 2008-2019 亿联网络 版权所有 备案号:粤ICP备14031511号-2