From b4d90ade7ae559fc98f61b735a9bab243300291a Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 18 May 2016 22:33:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BModel=E7=B1=BB=E7=9A=84db?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20=E5=B9=B6=E5=A2=9E=E5=8A=A0query=E5=B1=9E?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Model.php | 78 ++++++++++++++++++-------------- library/think/model/Merge.php | 51 +++++++++++++-------- library/think/model/Relation.php | 2 +- 3 files changed, 75 insertions(+), 56 deletions(-) diff --git a/library/think/Model.php b/library/think/Model.php index b0a2e28b..7d5455b8 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -34,6 +34,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess protected $name; // 数据表名称 protected $table; + // 查询对象 + protected $query; // 回调事件 protected static $event = []; @@ -99,10 +101,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } else { $this->data = $data; } + if (empty($this->name)) { $this->name = basename(str_replace('\\', '/', get_class($this))); } + // 当前模型的查询对象 + $this->query = $this->db(); + // 执行初始化操作 $this->initialize(); } @@ -233,7 +239,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess public function getPk($table = '') { if (empty($this->pk)) { - $this->pk = self::db()->getTableInfo($table, 'pk'); + $this->pk = $this->query->getTableInfo($table, 'pk'); } return $this->pk; } @@ -301,7 +307,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return false; } - $db = self::db(); if ($this->isUpdate) { // 自动更新 $this->autoCompleteData($this->update); @@ -330,7 +335,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } } - $result = $db->where($where)->update($data); + $result = $this->query->where($where)->update($data); // 更新回调 $this->trigger('after_update', $this); @@ -347,11 +352,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return false; } - $result = $db->insert($this->data); + $result = $this->query->insert($this->data); // 获取自动增长主键 if ($result && $getId) { - $insertId = $db->getLastInsID(); + $insertId = $this->query->getLastInsID(); $pk = $this->getPk(); if (is_string($pk) && $insertId) { $this->data[$pk] = $insertId; @@ -443,7 +448,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return false; } - $result = self::db()->delete($this->data); + $result = $this->query->delete($this->data); $this->trigger('after_delete', $this); return $result; @@ -648,15 +653,16 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function destroy($data) { - $db = self::db(); + $model = new static(); + $query = $model->db(); if (is_array($data) && key($data) !== 0) { - $db->where($data); + $query->where($data); $data = []; } elseif ($data instanceof \Closure) { - call_user_func_array($data, [ & $db]); + call_user_func_array($data, [ & $query]); $data = []; } - $resultSet = $db->select($data); + $resultSet = $query->select($data); $result = false; if ($resultSet) { foreach ($resultSet as $data) { @@ -676,9 +682,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess public static function scope($name, $params = []) { $model = new static(); - $class = self::db(); + $query = $model->db(); if ($name instanceof \Closure) { - call_user_func_array($name, [ & $class, $params]); + call_user_func_array($name, [ & $query, $params]); } elseif ($name instanceof Query) { return $name; } else { @@ -686,7 +692,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess foreach ($names as $scope) { $method = 'scope' . $scope; if (method_exists($model, $method)) { - $model->$method($class, $params); + $model->$method($query, $params); } } } @@ -704,10 +710,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function has($relation, $operator = '>=', $count = 1, $id = '*') { - $class = new static(); - $info = $class->$relation()->getRelationInfo(); + $model = new static(); + $info = $model->$relation()->getRelationInfo(); $table = $info['model']::getTable(); - return self::db()->alias('a') + return $model->db()->alias('a') ->join($table . ' b', 'a.' . $info['localKey'] . '=b.' . $info['foreignKey']) ->group('b.' . $info['foreignKey']) ->having('count(' . $id . ')' . $operator . $count); @@ -722,8 +728,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public static function hasWhere($relation, $where = []) { - $class = new static(); - $info = $class->$relation()->getRelationInfo(); + $model = new static(); + $info = $model->$relation()->getRelationInfo(); $table = $info['model']::getTable(); if (is_array($where)) { foreach ($where as $key => $val) { @@ -733,7 +739,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } } } - return self::db()->alias('a') + return $model->db()->alias('a') ->field('a.*') ->join($table . ' b', 'a.' . $info['localKey'] . '=b.' . $info['foreignKey']) ->where($where); @@ -870,28 +876,25 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } /** - * 初始化数据库对象 - * @access protected + * 获取当前模型的数据库查询对象 + * @access public * @return \think\db\Query */ - protected static function db() + public function db() { $model = get_called_class(); if (!isset(self::$links[$model])) { - $class = new static(); - // 设置当前模型 确保查询返回模型对象 - self::$links[$model] = Db::connect($class->connection)->model($model); + $query = Db::connect($this->connection)->model($model); // 设置当前数据表和模型名 - if (!empty($class->table)) { - self::$links[$model]->setTable($class->table); + if (!empty($this->table)) { + $query->setTable($this->table); } else { - $name = !empty($class->name) ? $class->name : basename(str_replace('\\', '/', $model)); - self::$links[$model]->name($name); + $query->name($this->name); } + self::$links[$model] = $query; } - // 返回当前模型的数据库查询对象 return self::$links[$model]; } @@ -901,18 +904,23 @@ abstract class Model implements \JsonSerializable, \ArrayAccess if (method_exists($this, 'scope' . $method)) { // 动态调用命名范围 $method = 'scope' . $method; - $class = self::db(); - array_unshift($args, $class); + array_unshift($args, $this->query); call_user_func_array([$this, $method], $args); return $this; } else { - return call_user_func_array([self::db(), $method], $args); + return call_user_func_array([$this->query, $method], $args); } } public static function __callStatic($method, $params) { - return call_user_func_array([self::db(), $method], $params); + $model = get_called_class(); + if (!isset(self::$links[$model])) { + $class = new static(); + self::$links[$model] = $class->db(); + } + $query = self::$links[$model]; + return call_user_func_array([$query, $method], $params); } /** @@ -926,7 +934,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess { if (is_null($this->fieldType)) { // 获取字段类型信息并缓存 - $this->fieldType = self::db()->getTableInfo('', 'type'); + $this->fieldType = $this->query->getTableInfo('', 'type'); } if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime, $this->deleteTime])) { // 自动写入的时间戳字段 diff --git a/library/think/model/Merge.php b/library/think/model/Merge.php index 05918fac..f21931a8 100644 --- a/library/think/model/Merge.php +++ b/library/think/model/Merge.php @@ -61,14 +61,14 @@ class Merge extends Model { $class = new static(); $master = $class->name; - $fields = self::getModelField($master, '', $class->mapFields); + $fields = self::getModelField($query, $master, '', $class->mapFields); $query->alias($master)->field($fields); foreach (static::$relationModel as $key => $model) { $name = is_int($key) ? $model : $key; $table = is_int($key) ? $query->getTable($name) : $model; $query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk()); - $fields = self::getModelField($name, $table, $class->mapFields); + $fields = self::getModelField($query, $name, $table, $class->mapFields); $query->field($fields); } return $query; @@ -77,15 +77,16 @@ class Merge extends Model /** * 获取关联模型的字段 并解决混淆 * @access protected + * @param \think\db\Query $query 查询对象 * @param string $name 模型名称 * @param string $table 关联表名称 * @param array $map 字段映射 * @return array */ - protected static function getModelField($name, $table = '', $map = []) + protected static function getModelField($query, $name, $table = '', $map = []) { // 获取模型的字段信息 - $fields = self::db()->getTableInfo($table, 'fields'); + $fields = $query->getTableInfo($table, 'fields'); $array = []; foreach ($fields as $field) { if ($key = array_search($name . '.' . $field, $map)) { @@ -163,11 +164,16 @@ class Merge extends Model } // 数据自动完成 $this->autoCompleteData($this->auto); + + // 自动写入更新时间 + if ($this->autoWriteTimestamp) { + $this->__set($this->updateTime, null); + } + // 处理模型数据 $data = $this->parseData($this->name, $this->data); - $db = self::db(); - $db->startTrans('merge_save_' . $this->name); + $this->query->startTrans('merge_save_' . $this->name); try { if ($this->isUpdate) { // 自动写入 @@ -178,15 +184,15 @@ class Merge extends Model } // 写入主表数据 - $result = $db->strict(false)->update($data); + $result = $this->query->strict(false)->update($data); // 写入附表数据 foreach (static::$relationModel as $key => $model) { $name = is_int($key) ? $model : $key; - $table = is_int($key) ? $db->getTable($model) : $model; + $table = is_int($key) ? $this->query->getTable($model) : $model; // 处理关联模型数据 $data = $this->parseData($name, $this->data); - $query = clone $db; + $query = clone $this->query; $query->table($table)->strict(false)->where($this->fk, $this->data[$this->getPk()])->update($data); } // 新增回调 @@ -195,6 +201,11 @@ class Merge extends Model // 自动写入 $this->autoCompleteData($this->insert); + // 自动写入创建时间 + if ($this->autoWriteTimestamp) { + $this->__set($this->createTime, null); + } + if (false === $this->trigger('before_insert', $this)) { return false; } @@ -209,10 +220,10 @@ class Merge extends Model // 写入附表数据 foreach (static::$relationModel as $key => $model) { $name = is_int($key) ? $model : $key; - $table = is_int($key) ? $db->getTable($model) : $model; + $table = is_int($key) ? $this->query->getTable($model) : $model; // 处理关联模型数据 $data = $this->parseData($name, $this->data, true); - $query = clone $db; + $query = clone $this->query; $query->table($table)->strict(false)->insert($data); } $result = $insertId; @@ -220,10 +231,10 @@ class Merge extends Model // 新增回调 $this->trigger('after_insert', $this); } - $db->commit('merge_save_' . $this->name); + $this->query->commit('merge_save_' . $this->name); return $result; } catch (\PDOException $e) { - $db->rollback(); + $this->query->rollback(); return false; } } @@ -238,26 +249,26 @@ class Merge extends Model if (false === $this->trigger('before_delete', $this)) { return false; } - $db = self::db(); - $db->startTrans('merge_delete_' . $this->name); + + $this->query->startTrans('merge_delete_' . $this->name); try { - $result = $db->delete($this->data); + $result = $this->query->delete($this->data); if ($result) { // 获取主键数据 $pk = $this->data[$this->getPk()]; // 删除关联数据 foreach (static::$relationModel as $key => $model) { - $table = is_int($key) ? $db->getTable($model) : $model; - $query = clone $db; + $table = is_int($key) ? $this->query->getTable($model) : $model; + $query = clone $this->query; $query->table($table)->where($this->fk, $pk)->delete(); } } $this->trigger('after_delete', $this); - $db->commit('merge_delete_' . $this->name); + $this->query->commit('merge_delete_' . $this->name); return $result; } catch (\PDOException $e) { - $db->rollback(); + $this->query->rollback(); return false; } } diff --git a/library/think/model/Relation.php b/library/think/model/Relation.php index a2673237..65e066ab 100644 --- a/library/think/model/Relation.php +++ b/library/think/model/Relation.php @@ -593,7 +593,7 @@ class Relation { if ($this->model) { $model = new $this->model; - $db = $model::db(); + $db = $model->db(); if (self::HAS_MANY == $this->type && isset($this->parent->{$this->localKey})) { // 关联查询带入关联条件 $db->where($this->foreignKey, $this->parent->{$this->localKey});