getModel(); $attributes = $model->attributes; $fields = array_keys($attributes); foreach ($fields as $key) { if (isset($data[$key])) { $model->$key = $data[$key]; } } if (!$model->validate()) { // 验证失败: $errors 是一个包含错误信息的数组 \Yii::error(static::tableName() . ' -- model validate errors: ' . json_encode($model->errors)); util::fail('输入数据验证失败'); } // 保存数据并检查结果 if (!$model->save()) { $errors = $model->errors; \Yii::error(static::tableName() . ' -- save failed: ' . json_encode($errors)); throw new \Exception('数据保存失败: ' . json_encode($errors)); } return $returnObject ? $model : $model->attributes; } /** * 批量添加 * @param array $data 二维数组 [['name'=>'a'], ['name'=>'b']] * @return void */ public function batchAdd($data) { $model = $this->getModel(); foreach ($data as $attributes) { $newModel = clone $model; // false 不检测字段安全 true 需要在model设置rules $newModel->setAttributes($attributes, false); $newModel->save(); } } /** * 获取表的所有字段名 * @return array */ public function getFields() { $model = $this->getModel(); $attributes = $model->attributes; return array_keys($attributes); } /** * 根据主键ID删除一条记录 * @param int|string $id 主键ID * @return int|false 删除的行数,失败返回false * @throws \Throwable * @throws \yii\db\StaleObjectException */ public function deleteById($id) { $model = $this->getModel(); return $model::findOne($id)->delete(); } /** * 根据多个主键ID批量删除 * @param array $ids 主键ID数组 * @return int 删除的行数 */ public function deleteByIds($ids) { $model = $this->getModel(); return $model::deleteAll(['id' => $ids]); } /** * 根据条件删除一条或多条记录 * @param array $condition 查询条件 * @return int 删除的行数 */ public function deleteByCondition($condition) { if (empty($condition)) { return 0; } $where = array(); $variable = array(); foreach ($condition as $key => $val) { $where[] = $key . '=:' . $key; $variable[':' . $key] = $val; } $whereString = implode(' and ', $where); $count = self::deleteAll($whereString, $variable); return $count; } /** * 根据主键ID更新一条记录 * @param int|string $id 主键ID * @param array $data 更新的数据 * @return array ['status' => bool, 'data' => array] status=true更新成功,false更新失败 */ public function updateById($id, $data) { $model = $this->getModel(); $attributes = $model->attributes; $fields = array_keys($attributes); foreach ($data as $key => $val) { if (in_array($key, $fields) == false) { //删除表里不存在字段 unset($data[$key]); } } $re = self::updateAll($data, 'id=:id', ['id' => $id]); if ($re == 1) { return ['status' => true, 'data' => $data]; } return ['status' => false, 'data' => $data]; } /** * 根据多个主键ID批量更新 * @param array $ids 主键ID数组 * @param array $data 更新的数据 * @return int 更新的行数 */ public function updateByIds($ids, $data) { return self::updateAll($data, ['id' => $ids]); } /** * 根据条件更新一条或多条记录 * @param array $condition 查询条件 * @param array $data 更新的数据 * @return int 更新的行数 */ public function updateByCondition($condition, $data) { $where = array(); $variable = array(); foreach ($condition as $key => $val) { $where[] = $key . '=:' . $key; $variable[':' . $key] = $val; } $whereString = implode(' and ', $where); $count = self::updateAll($data, $whereString, $variable); return $count; } /** * 根据主键ID查出一条记录 * @param int|string $id 主键ID * @param bool $returnObject 是否返回对象 * @param string|array $field 查询字段 * @return array|ActiveRecord|null * @throws \Exception */ public function getById($id, $returnObject = false, $field = '*') { $query = $this->conditionQuery(['id' => $id])->select($field); if ($returnObject == false) { return $query->asArray()->one(); } else { return $query->one(); } } /** * 根据条件查出一条记录 * @param array $condition 查询条件 * @param bool $returnObject 是否返回对象 * @param string|array|bool $order 排序 * @param string|array $field 查询字段 * @return array|ActiveRecord|null * @throws \Exception */ public function getByCondition($condition, $returnObject = false, $order = false, $field = '*') { $query = $this->conditionQuery($condition)->select($field); if (isset($order)) { $query->orderBy($order); } return $returnObject == true ? $query->one() : $query->asArray()->one(); } /** * 获取第一条记录 (通常用于获取任意一条或结合排序获取特定一条) * @param bool $returnObject 是否返回对象 * @param string|array|bool $order 排序 * @param string|array $field 查询字段 * @return array|ActiveRecord|null * @throws \Exception */ public function getOne($returnObject = false, $order = false, $field = '*') { $query = $this->conditionQuery([])->select($field); if (isset($order)) { $query->orderBy($order); } return $returnObject == true ? $query->one() : $query->asArray()->one(); } /** * 构建查询条件对象 * 支持查询条件包括: * $condition = [ * 'name' => 'john', // 等于 * 'id>' => 3, // 大于 * 'id<' => 10, // 小于 * 'id>=' => 3, // 大于等于 * 'id<=' => 10, // 小于等于 * 'id!=' => -1, // 不等于 * 'id' => ['in', [10,11,12]], // IN * 'id' => ['not in', [10,11,12]], // NOT IN * 'age' => ['between', [20,30]], // BETWEEN * 'name' => ['like', 'Jack'] // LIKE * ]; * @param array $condition 查询条件数组 * @return \yii\db\ActiveQuery * @throws \Exception */ public function conditionQuery($condition = []) { $whereNum = 0; $query = self::find(); if (!empty($condition)) { foreach ($condition as $key => $val) { $param = [$key => $val]; if (strstr($key, '!=')) { //不等于 $pos = strpos($key, '!='); $currentKey = substr($key, 0, $pos); $param = ['!=', $currentKey, $val]; } elseif (strstr($key, '>=')) { //大于等于 $pos = strpos($key, '>='); $currentKey = substr($key, 0, $pos); $param = ['>=', $currentKey, $val]; } elseif (strstr($key, '<=')) { //小于等于 $pos = strpos($key, '<='); $currentKey = substr($key, 0, $pos); $param = ['<=', $currentKey, $val]; } elseif (strstr($key, '>')) { //大于 $pos = strpos($key, '>'); $currentKey = substr($key, 0, $pos); $param = ['>', $currentKey, $val]; } elseif (strstr($key, '<')) { //小于 $pos = strpos($key, '<'); $currentKey = substr($key, 0, $pos); $param = ['<', $currentKey, $val]; } elseif (is_array($val)) { if (count($val) != 2) { util::fail('参数不至2个,非法查询方式:' . json_encode($condition)); } if ($val[0] == 'in') { $param = ['in', $key, $val[1]]; } elseif ($val[0] == 'not in') { $param = ['not in', $key, $val[1]]; } elseif ($val[0] == 'between') { $param = ['between', $key, $val[1][0], $val[1][1]]; } elseif ($val[0] == 'like') { $param = ['like', $key, $val[1]]; } else { util::fail('非法查询方式:' . json_encode($condition)); } } else { } if ($whereNum == 0) { $query->where($param); } else { $query->andWhere($param); } $whereNum++; } } return $query; } /** * 判断数据是否存在 * @param array $condition 查询条件 * @return bool * @throws \Exception */ public function exists($condition) { return $this->conditionQuery($condition)->exists(); } /** * 根据条件查出多条记录 * @param array $condition 查询条件 * @param string|array|null $order 排序 * @param string|array $field 查询字段 * @param string|callable|null $indexBy 索引字段 * @param bool $returnObject 是否返回对象 * @return array|ActiveRecord[] * @throws \Exception */ public function getAllByCondition($condition, $order = null, $field, $indexBy = null, $returnObject = false) { $query = $this->conditionQuery($condition)->select($field); if (isset($indexBy)) { $query->indexBy($indexBy); } if (isset($order)) { $query->orderBy($order); } if ($returnObject == false) { return $query->asArray()->all(); } else { return $query->all(); } } /** * 根据多个主键ID查询多条记录 * @param array $ids 主键ID数组 * @param string|array|null $order 排序 * @param string|callable|null $indexBy 索引字段 * @param string|array $field 查询字段 * @return array * @throws \Exception */ public function getByIds($ids, $order = null, $indexBy = null, $field = '*') { $data = []; if (empty($ids)) { return $data; } $query = $this->conditionQuery(['id' => ['in', $ids]])->select($field); if (isset($indexBy)) { $query->indexBy($indexBy); } if (!empty($order)) { $query->order($order); } $data = $query->asArray()->all(); return $data; } /** * 根据条件获取记录数量 * @param array $condition 查询条件 * @return int|string * @throws \Exception */ public function getCount($condition) { return $this->conditionQuery($condition)->count(); } /** * 分页查询列表 * @param string|array $field 查询字段 * @param array $where 查询条件 * @param int $page 当前页码 * @param int $pageSize 每页数量 * @param string|array $order 排序 * @param string|array $with 关联查询 * @return array ['totalNum' => int, 'totalPage' => int, 'moreData' => int, 'list' => array] * @throws \Exception */ public function getList($field, $where, $page, $pageSize, $order = '', $with = '') { $offset = ($page - 1) * $pageSize; $query = $this->conditionQuery($where)->select($field); $clone = clone $query; $count = $clone->count(); $totalPage = ceil($count / $pageSize); $data['totalNum'] = $count; $data['totalPage'] = $totalPage;//总共页数 $data['moreData'] = $totalPage > $page ? 1 : 0;//是否还有更多数据 if (!empty($order)) { $query->orderBy($order); } if (!empty($with)) { $query->with($with); } $list = $query->offset($offset)->limit($pageSize)->asArray()->all(); $data['list'] = $list;//数据 return $data; } /** * 查询全部列表 (不分页) * @param string|array $field 查询字段 * @param array $where 查询条件 * @param string|array $order 排序 * @param string|array $with 关联查询 * @return array * @throws \Exception */ public function getAllList($field, $where, $order = '', $with = '') { $query = $this->conditionQuery($where)->select($field); if (!empty($order)) { $query->orderBy($order); } if (!empty($with)) { $query->with($with); } $list = $query->asArray()->all(); return $list; } /** * 查询指定条数的列表 * @param string|array $field 查询字段 * @param array $where 查询条件 * @param int $limit 限制条数 * @param string|array $order 排序 * @param string|array $with 关联查询 * @return array * @throws \Exception */ public function getLimitList($field, $where, $limit, $order = '', $with = '') { $offset = 0; $query = $this->conditionQuery($where)->select($field); if (!empty($order)) { $query->orderBy($order); } if (!empty($with)) { $query->with($with); } $list = $query->offset($offset)->limit($limit)->asArray()->all(); return $list; } /** * 更新计数器 (原子操作) * @param array $counters 更新的计数器数组,例如 ['view_count' => 1] 表示加1,['view_count' => -1] 表示减1 * @param array $condition 更新条件 * @param array $params 绑定参数 * @return int 更新行数 */ public function counters($counters, $condition, $params = []) { return self::updateAllCounters($counters, $condition, $params); } /** * 根据主键获取记录并锁定 (SELECT FOR UPDATE) * @param int|string $id 主键ID * @param string|array $field 查询字段 * @return array|ActiveRecord|null */ public function getLockById($id, $field = '*') { return self::findBySql('select ' . $field . ' from ' . static::tableName() . ' where id = :id for update', ['id' => $id])->one(); } /** * 求和 * @param array $condition 查询条件 * @param string $field 求和字段 * @return mixed * @throws \Exception */ public function sum($condition, $field) { return $this->conditionQuery($condition)->sum($field); } }