From 64030777283938f56a5036a2515dff0bb411b11d Mon Sep 17 00:00:00 2001 From: top_nuomi <1130395124@qq.com> Date: Tue, 3 Sep 2019 10:45:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BDatabase=E7=B1=BB=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DMySQL=E4=BA=8B=E5=8A=A1=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/library/Database.php | 97 +++++--- framework/library/Model.php | 18 +- framework/library/database/driver/MySQLi.php | 213 ++++++++++-------- .../database/driver/ObjectForMySQL.php | 118 +++++++--- 4 files changed, 282 insertions(+), 164 deletions(-) diff --git a/framework/library/Database.php b/framework/library/Database.php index b089fb4..c4c4ff0 100644 --- a/framework/library/Database.php +++ b/framework/library/Database.php @@ -244,9 +244,15 @@ class Database */ public function join($type, $table, $name) { + $tableName = null; + if (is_array($table) && isset($table[0]) && isset($table[1])) { + $tableName = $table[0] . $table[1]; + } else { + $tableName = $this->config['prefix'] . $table; + } $this->join[] = [ $type, - $this->config['prefix'] . $table, + $tableName, $name ]; return $this; @@ -285,13 +291,14 @@ class Database if (is_callable($param)) $param($this); $field = $this->getPk(); - if (!empty($this->join)) { - $this->table .= ' as this'; - $field = 'this.' . $field; - } + $pkWhere = []; if (!is_bool($param) && !is_callable($param)) - $this->where([$field => $param]); - $result = self::$driver->find($this->table, $this->distinct, $this->field, $this->join, $this->on, $this->where, $this->order); + $pkWhere = [$field => $param]; + $result = self::$driver->find([ + $this->table, + !empty($this->join), + $pkWhere + ], $this->distinct, $this->field, $this->join, $this->on, $this->where, $this->order); $this->_reset(); return $result; } @@ -307,13 +314,14 @@ class Database if (is_callable($param)) $param($this); $field = $this->getPk(); - if (!empty($this->join)) { - $this->table .= ' as this'; - $field = 'this.' . $field; - } + $pkWhere = []; if (!is_bool($param) && !is_callable($param)) - $this->where([$field => $param]); - $result = self::$driver->select($this->table, $this->distinct, $this->field, $this->join, $this->on, $this->where, $this->order, $this->limit); + $pkWhere = [$field => $param]; + $result = self::$driver->select([ + $this->table, + !empty($this->join), + $pkWhere + ], $this->distinct, $this->field, $this->join, $this->on, $this->where, $this->order, $this->limit); $this->_reset(); foreach ($result as $k => $v) $result[$k] = $v; @@ -332,13 +340,14 @@ class Database if (is_callable($param)) $param($this); $field = $this->getPk(); - if (!empty($this->join)) { - $this->table .= ' as this'; - $field = 'this.' . $field; - } + $pkWhere = []; if (!is_bool($param) && !is_callable($param)) - $this->where([$field => $param]); - $result = self::$driver->update($this->table, $this->join, $this->on, $this->where, $this->order, $this->limit, $data); + $pkWhere = [$field => $param]; + $result = self::$driver->update([ + $this->table, + !empty($this->join), + $pkWhere + ], $this->join, $this->on, $this->where, $this->order, $this->limit, $data); $this->_reset(); return $result; } @@ -355,14 +364,14 @@ class Database $param($this); } $field = $this->getPk(); - if (!empty($this->join)) { - $this->table .= ' as this'; - $field = 'this.' . $field; - } - if (!is_bool($param) && !is_callable($param)) { - $this->where([$field => $param]); - } - $result = self::$driver->delete($this->effect, $this->table, $this->join, $this->on, $this->where, $this->order, $this->limit); + $pkWhere = []; + if (!is_bool($param) && !is_callable($param)) + $pkWhere = [$field => $param]; + $result = self::$driver->delete($this->effect, [ + $this->table, + !empty($this->join), + $pkWhere + ], $this->join, $this->on, $this->where, $this->order, $this->limit); $this->_reset(); return $result; @@ -380,13 +389,14 @@ class Database if (is_callable($param)) { $param($this); } - if (!empty($this->join)) { - $this->table .= ' as this'; - } if (empty($this->field) && $param && !is_callable($param)) { $this->field = $param; } - $result = self::$driver->common($this->table, $this->distinct, $this->field, $this->join, $this->on, $this->where, $type); + $result = self::$driver->common([ + $this->table, + !empty($this->join), + [] + ], $this->distinct, $this->field, $this->join, $this->on, $this->where, $type); $this->_reset(); return $result; @@ -421,13 +431,27 @@ class Database } /** - * MySQL事务 - * @param $action - * @return mixed + * 开启事务 */ - public function transaction($action) + public function begin() { - return self::$driver->transaction($action); + self::$driver->begin(); + } + + /** + * 提交 + */ + public function commit() + { + self::$driver->commit(); + } + + /** + * 回滚 + */ + public function rollback() + { + self::$driver->rollback(); } /** @@ -453,7 +477,6 @@ class Database $this->where = []; $this->order = null; $this->limit = null; - $this->table = str_ireplace(' as this', '', $this->table); } /** diff --git a/framework/library/Model.php b/framework/library/Model.php index 7a82f9b..e1acadb 100644 --- a/framework/library/Model.php +++ b/framework/library/Model.php @@ -2,6 +2,8 @@ namespace top\library; +use top\library\exception\DatabaseException; + /** * 基础模型 * @author topnuomi 2018年11月23日 @@ -340,7 +342,19 @@ class Model */ public function transaction($action) { - return $this->getDb()->transaction($action); + $db = $this->getDb(); + // 开启事务 + $db->begin(); + try { + $action(); + // 执行操作后提交 + $db->commit(); + return true; + } catch (DatabaseException $exception) { + // 回滚 + $db->rollback(); + return false; + } } /** @@ -367,7 +381,7 @@ class Model return $mapData; } else { $data = []; - $prefix = Config::instance()->get('db')['prefix']; + $prefix = $this->prefix ? $this->prefix : Config::instance()->get('db')['prefix']; $tableDesc = $this->tableDesc($prefix . $this->table); foreach ($tableDesc as $value) { if (array_key_exists($value['Field'], $mapData)) { diff --git a/framework/library/database/driver/MySQLi.php b/framework/library/database/driver/MySQLi.php index 55c4e0b..453727e 100644 --- a/framework/library/database/driver/MySQLi.php +++ b/framework/library/database/driver/MySQLi.php @@ -80,11 +80,13 @@ class MySQLi implements DatabaseIfs public function update($table, $join, $on, $where, $order, $limit, $data) { // TODO Auto-generated method stub - $join = $this->processJoin($join, $on); - $where = $this->processWhere($where); - $order = $this->processOrder($order); - $limit = $this->processLimit($limit); - $query = 'update ' . $table . "{$join} set "; + $tableInfo = $this->parseTable($table); + $join = $this->parseJoin($join, $on); + array_push($where, $tableInfo['where']); + $where = $this->parseWhere($where); + $order = $this->parseOrder($order); + $limit = $this->parseLimit($limit); + $query = "update {$tableInfo['table']}{$join} set "; $updateData = []; foreach ($data as $key => $value) { if (!is_numeric($value) && !$value) { @@ -114,16 +116,18 @@ class MySQLi implements DatabaseIfs public function find($table, $distinct, $field, $join, $on, $where, $order) { // TODO Auto-generated method stub - $join = $this->processJoin($join, $on); - $distinct = $this->processDistinct($distinct); + $tableInfo = $this->parseTable($table); + $join = $this->parseJoin($join, $on); + $distinct = $this->parseDistinct($distinct); if ($distinct) { $field = $distinct; } else { - $field = $this->processField($field); + $field = $this->parseField($field); } - $where = $this->processWhere($where); - $order = $this->processOrder($order); - $this->sql = "select {$field} from $table{$join}{$where}{$order} limit 1"; + array_push($where, $tableInfo['where']); + $where = $this->parseWhere($where); + $order = $this->parseOrder($order); + $this->sql = "select {$field} from {$tableInfo['table']}{$join}{$where}{$order} limit 1"; $result = $this->query($this->sql); return mysqli_fetch_assoc($result); } @@ -144,17 +148,19 @@ class MySQLi implements DatabaseIfs public function select($table, $distinct, $field, $join, $on, $where, $order, $limit) { // TODO Auto-generated method stub - $join = $this->processJoin($join, $on); - $distinct = $this->processDistinct($distinct); + $tableInfo = $this->parseTable($table); + $join = $this->parseJoin($join, $on); + $distinct = $this->parseDistinct($distinct); if ($distinct) { $field = $distinct; } else { - $field = $this->processField($field); + $field = $this->parseField($field); } - $where = $this->processWhere($where); - $order = $this->processOrder($order); - $limit = $this->processLimit($limit); - $this->sql = "select {$field} from {$table}{$join}{$where}{$order}{$limit}"; + array_push($where, $tableInfo['where']); + $where = $this->parseWhere($where); + $order = $this->parseOrder($order); + $limit = $this->parseLimit($limit); + $this->sql = "select {$field} from {$tableInfo['table']}{$join}{$where}{$order}{$limit}"; $result = $this->query($this->sql); return mysqli_fetch_all($result, MYSQLI_ASSOC); } @@ -174,12 +180,14 @@ class MySQLi implements DatabaseIfs public function delete($effect, $table, $join, $on, $where, $order, $limit) { // TODO Auto-generated method stub - $effect = $this->effect($effect); - $join = $this->processJoin($join, $on); - $where = $this->processWhere($where); - $order = $this->processOrder($order); - $limit = $this->processLimit($limit); - $this->sql = "delete{$effect} from $table{$join}{$where}{$order}{$limit}"; + $tableInfo = $this->parseTable($table); + $effect = $this->parseEffect($effect); + $join = $this->parseJoin($join, $on); + array_push($where, $tableInfo['where']); + $where = $this->parseWhere($where); + $order = $this->parseOrder($order); + $limit = $this->parseLimit($limit); + $this->sql = "delete{$effect} from {$tableInfo['table']}{$join}{$where}{$order}{$limit}"; $this->query($this->sql); return mysqli_affected_rows($this->link); } @@ -200,27 +208,6 @@ class MySQLi implements DatabaseIfs return $data; } - /** - * 计数 - * @param $table - * @param $field - * @param $join - * @param $on - * @param $where - * @return mixed - * @throws \Exception - */ - public function count($table, $field, $join, $on, $where) - { - $field = $this->processField($field); - $join = $this->processJoin($join, $on); - $where = $this->processWhere($where); - $this->sql = "select count({$field}) from $table{$join}{$where}"; - $result = $this->query($this->sql); - $count = mysqli_fetch_array($result); - return $count[0]; - } - /** * 公共方法 * @param $table @@ -234,15 +221,17 @@ class MySQLi implements DatabaseIfs */ public function common($table, $distinct, $field, $join, $on, $where, $type) { - $distinct = $this->processDistinct($distinct); + $tableInfo = $this->parseTable($table); + $distinct = $this->parseDistinct($distinct); if ($distinct) { $field = $distinct; } else { - $field = $this->processField($field); + $field = $this->parseField($field); } - $join = $this->processJoin($join, $on); - $where = $this->processWhere($where); - $this->sql = "select {$type}({$field}) from {$table}{$join}{$where}"; + $join = $this->parseJoin($join, $on); + array_push($where, $tableInfo['where']); + $where = $this->parseWhere($where); + $this->sql = "select {$type}({$field}) from {$tableInfo['table']}{$join}{$where}"; $result = $this->query($this->sql); $data = mysqli_fetch_array($result); if (isset($data[0])) { @@ -252,6 +241,30 @@ class MySQLi implements DatabaseIfs } } + /** + * 事务 + */ + public function begin() + { + mysqli_begin_transaction($this->link); + } + + /** + * 提交 + */ + public function commit() + { + mysqli_commit($this->link); + } + + /** + * 回滚 + */ + public function rollback() + { + mysqli_rollback($this->link); + } + /** * 执行SQL * @param string $query @@ -264,29 +277,10 @@ class MySQLi implements DatabaseIfs if (!$result) { throw new DatabaseException(mysqli_error($this->link)); } - // $this->writeLogs($result, $query); + $this->writeLogs($result, $query); return $result; } - /** - * MySQL事务 - * @param $action - * @return bool - * @throws DatabaseException - */ - public function transaction($action) - { - try { - $this->query('start transaction'); - $action(); - $this->query('commit'); - return true; - } catch (DatabaseException $e) { - $this->query('rollback'); - throw new DatabaseException($e->getMessage()); - } - } - /** * 获取执行的最后一条SQL * @@ -297,7 +291,37 @@ class MySQLi implements DatabaseIfs return trim($this->sql, ' '); } - public function effect($effect) + /** + * 解析表信息 + * @param $table + * @return array + */ + private function parseTable($table) + { + $info = []; + // 如果是多表查询,给当前表名别名this + if ($table[1] === true) { + $info['table'] = $table[0] . ' as this'; + $info['where'] = []; + // 如果存在主键的条件,给键名加上别名 + if (!empty($table[2])) { + $field = 'this.' . array_keys($table[2])[0]; + $value = array_values($table[2])[0]; + $info['where'] = [$field => $value]; + } + } else { + $info['table'] = $table[0]; + $info['where'] = $table[2]; + } + return $info; + } + + /** + * 解析多表的删除 + * @param $effect + * @return string + */ + public function parseEffect($effect) { if ($effect) { if (is_array($effect)) { @@ -308,7 +332,12 @@ class MySQLi implements DatabaseIfs return ''; } - private function processDistinct($distinct) + /** + * 解析数据去重 + * @param $distinct + * @return string + */ + private function parseDistinct($distinct) { if ($distinct) { if (is_array($distinct)) { @@ -324,7 +353,7 @@ class MySQLi implements DatabaseIfs * @param string|array $field * @return string */ - private function processField($field) + private function parseField($field) { if (!$field) { $field = '*'; @@ -340,7 +369,7 @@ class MySQLi implements DatabaseIfs * @param string $glue * @return string */ - private function processWhere(array $array, $glue = 'and') + private function parseWhere(array $array, $glue = 'and') { $where = []; foreach ($array as $value) { @@ -384,7 +413,7 @@ class MySQLi implements DatabaseIfs * @param string $order * @return string */ - private function processOrder($order = '') + private function parseOrder($order = '') { if ($order) { $order = ' order by ' . $order; @@ -397,7 +426,7 @@ class MySQLi implements DatabaseIfs * @param string $limit * @return string */ - private function processLimit($limit = '') + private function parseLimit($limit = '') { if ($limit) { if (is_array($limit)) { @@ -415,20 +444,23 @@ class MySQLi implements DatabaseIfs * @param string|array $on * @return string */ - private function processJoin($data, $on) + private function parseJoin($data, $on) { $join = []; for ($i = 0; $i < count($data); $i++) { - if (is_array($on[$i])) { - $pieces = []; - foreach ($on[$i] as $key => $value) { - $pieces[] = $key . ' = ' . $value; + $string = null; + if (isset($on[$i])) { + if (is_array($on[$i])) { + $pieces = []; + foreach ($on[$i] as $key => $value) { + $pieces[] = $key . ' = ' . $value; + } + $string = ' on ' . implode(' and ', $pieces); + } else { + $string = ' on ' . $on[$i]; } - $onString = implode(' and ', $pieces); - } else { - $onString = $on[$i]; } - $join[] = $data[$i][0] . ' join ' . $data[$i][1] . ($data[$i][2] ? ' as ' . $data[$i][2] : '') . ' on ' . $onString; + $join[] = $data[$i][0] . ' join ' . $data[$i][1] . ($data[$i][2] ? ' as ' . $data[$i][2] : '') . $string; } if (!empty($join)) { return ' ' . implode(' ', $join); @@ -461,6 +493,11 @@ class MySQLi implements DatabaseIfs return $value; } + /** + * SQL存文件 + * @param $result + * @param $query + */ private function writeLogs($result, $query) { if (DEBUG) { @@ -469,10 +506,8 @@ class MySQLi implements DatabaseIfs $error = mysqli_error($this->link); } $nowTime = date('Y-m-d H:i:s', time()); - $content = <<parseTable($table); $join = $this->parseJoin($join, $on); + array_push($where, $tableInfo['where']); $where = $this->parseWhere($where); $order = $this->parseOrder($order); $limit = $this->parseLimit($limit); - $query = 'update ' . $table . "{$join} set "; + $query = 'update ' . $tableInfo['table'] . "{$join} set "; $updateData = []; foreach ($data as $key => $value) { if (!is_numeric($value) && !$value) { $value = 'NULL'; } else { - $value = '\'' . $this->mysqli->real_escape_string($value) . '\''; + $value = '\'' . mysqli_real_escape_string($this->link, $value) . '\''; } $updateData[] = $key . '=' . $value; } @@ -111,6 +113,7 @@ class ObjectForMySQL implements DatabaseIfs public function find($table, $distinct, $field, $join, $on, $where, $order) { // TODO Auto-generated method stub + $tableInfo = $this->parseTable($table); $join = $this->parseJoin($join, $on); $distinct = $this->parseDistinct($distinct); if ($distinct) { @@ -118,9 +121,10 @@ class ObjectForMySQL implements DatabaseIfs } else { $field = $this->parseField($field); } + array_push($where, $tableInfo['where']); $where = $this->parseWhere($where); $order = $this->parseOrder($order); - $this->sql = "select {$field} from $table{$join}{$where}{$order} limit 1"; + $this->sql = "select {$field} from {$tableInfo['table']}{$join}{$where}{$order} limit 1"; $result = $this->query($this->sql); return $result->fetch_assoc(); } @@ -141,6 +145,7 @@ class ObjectForMySQL implements DatabaseIfs public function select($table, $distinct, $field, $join, $on, $where, $order, $limit) { // TODO Auto-generated method stub + $tableInfo = $this->parseTable($table); $join = $this->parseJoin($join, $on); $distinct = $this->parseDistinct($distinct); if ($distinct) { @@ -148,10 +153,11 @@ class ObjectForMySQL implements DatabaseIfs } else { $field = $this->parseField($field); } + array_push($where, $tableInfo['where']); $where = $this->parseWhere($where); $order = $this->parseOrder($order); $limit = $this->parseLimit($limit); - $this->sql = "select {$field} from {$table}{$join}{$where}{$order}{$limit}"; + $this->sql = "select {$field} from {$tableInfo['table']}{$join}{$where}{$order}{$limit}"; $result = $this->query($this->sql); return $result->fetch_all(MYSQLI_ASSOC); } @@ -171,12 +177,14 @@ class ObjectForMySQL implements DatabaseIfs public function delete($effect, $table, $join, $on, $where, $order, $limit) { // TODO Auto-generated method stub + $tableInfo = $this->parseTable($table); $effect = $this->parseEffect($effect); $join = $this->parseJoin($join, $on); + array_push($where, $tableInfo['where']); $where = $this->parseWhere($where); $order = $this->parseOrder($order); $limit = $this->parseLimit($limit); - $this->sql = "delete{$effect} from $table{$join}{$where}{$order}{$limit}"; + $this->sql = "delete{$effect} from {$tableInfo['table']}{$join}{$where}{$order}{$limit}"; $this->query($this->sql); return $this->mysqli->affected_rows; } @@ -197,27 +205,6 @@ class ObjectForMySQL implements DatabaseIfs return $data; } - /** - * 计数 - * @param $table - * @param $field - * @param $join - * @param $on - * @param $where - * @return mixed - * @throws DatabaseException - */ - public function count($table, $field, $join, $on, $where) - { - $field = $this->parseField($field); - $join = $this->parseJoin($join, $on); - $where = $this->parseWhere($where); - $this->sql = "select count({$field}) from $table{$join}{$where}"; - $result = $this->query($this->sql); - $count = $result->fetch_array(); - return $count[0]; - } - /** * 公共方法 * @param $table @@ -232,6 +219,7 @@ class ObjectForMySQL implements DatabaseIfs */ public function common($table, $distinct, $field, $join, $on, $where, $type) { + $tableInfo = $this->parseTable($table); $distinct = $this->parseDistinct($distinct); if ($distinct) { $field = $distinct; @@ -239,8 +227,9 @@ class ObjectForMySQL implements DatabaseIfs $field = $this->parseField($field); } $join = $this->parseJoin($join, $on); + array_push($where, $tableInfo['where']); $where = $this->parseWhere($where); - $this->sql = "select {$type}({$field}) from {$table}{$join}{$where}"; + $this->sql = "select {$type}({$field}) from {$tableInfo['table']}{$join}{$where}"; $result = $this->query($this->sql); $data = $result->fetch_array(); if (isset($data[0])) { @@ -250,6 +239,30 @@ class ObjectForMySQL implements DatabaseIfs } } + /** + * 开启事务 + */ + public function begin() + { + $this->mysqli->begin_transaction(); + } + + /** + * 提交 + */ + public function commit() + { + $this->mysqli->commit(); + } + + /** + * 回滚 + */ + public function rollback() + { + $this->mysqli->rollback(); + } + /** * 执行SQL * @param string $query @@ -275,6 +288,36 @@ class ObjectForMySQL implements DatabaseIfs return trim($this->sql, ' '); } + /** + * 解析表信息 + * @param $table + * @return array + */ + private function parseTable($table) + { + $info = []; + // 如果是多表查询,给当前表名别名this + if ($table[1] === true) { + $info['table'] = $table[0] . ' as this'; + $info['where'] = []; + // 如果存在主键的条件,给键名加上别名 + if (!empty($table[2])) { + $field = 'this.' . array_keys($table[2])[0]; + $value = array_values($table[2])[0]; + $info['where'] = [$field => $value]; + } + } else { + $info['table'] = $table[0]; + $info['where'] = $table[2]; + } + return $info; + } + + /** + * 解析多表的删除 + * @param $effect + * @return string + */ public function parseEffect($effect) { if ($effect) { @@ -287,7 +330,7 @@ class ObjectForMySQL implements DatabaseIfs } /** - * + * 解析数据去重 * @param $distinct * @return string */ @@ -402,16 +445,19 @@ class ObjectForMySQL implements DatabaseIfs { $join = []; for ($i = 0; $i < count($data); $i++) { - if (is_array($on[$i])) { - $pieces = []; - foreach ($on[$i] as $key => $value) { - $pieces[] = $key . ' = ' . $value; + $string = null; + if (isset($on[$i])) { + if (is_array($on[$i])) { + $pieces = []; + foreach ($on[$i] as $key => $value) { + $pieces[] = $key . ' = ' . $value; + } + $string = ' on ' . implode(' and ', $pieces); + } else { + $string = ' on ' . $on[$i]; } - $onString = implode(' and ', $pieces); - } else { - $onString = $on[$i]; } - $join[] = $data[$i][0] . ' join ' . $data[$i][1] . ($data[$i][2] ? ' as ' . $data[$i][2] : '') . ' on ' . $onString; + $join[] = $data[$i][0] . ' join ' . $data[$i][1] . ($data[$i][2] ? ' as ' . $data[$i][2] : '') . $string; } if (!empty($join)) { return ' ' . implode(' ', $join);