Db类增加RESULTSET_ARRAY RESULTSET_COLLECTION 和 RESULTSET_CLASS 常量

数据库Connection类增加resultSetType属性定义 支持设置数据集返回类型
This commit is contained in:
thinkphp
2016-05-09 11:45:00 +08:00
parent 6723257a4b
commit 144a6132e6
9 changed files with 89 additions and 35 deletions

View File

@@ -16,6 +16,12 @@ namespace think;
*/ */
class Db class Db
{ {
// 数组数据集
const RESULTSET_ARRAY = 1;
// 对象数据集
const RESULTSET_COLLECTION = 2;
// 自定义对象数据集
const RESULTSET_CLASS = 3;
// 数据库连接实例 // 数据库连接实例
private static $instances = []; private static $instances = [];
// 查询次数 // 查询次数

View File

@@ -13,6 +13,7 @@ namespace think\db;
use PDO; use PDO;
use PDOStatement; use PDOStatement;
use think\Collection;
use think\Db; use think\Db;
use think\Debug; use think\Debug;
use think\Exception; use think\Exception;
@@ -52,6 +53,8 @@ abstract class Connection
/** @var PDO 当前连接ID */ /** @var PDO 当前连接ID */
protected $linkID; protected $linkID;
// 查询结果类型
protected $resultSetType = Db::RESULTSET_ARRAY;
// 查询结果类型 // 查询结果类型
protected $fetchType = PDO::FETCH_ASSOC; protected $fetchType = PDO::FETCH_ASSOC;
// 字段属性大小写 // 字段属性大小写
@@ -294,7 +297,7 @@ abstract class Connection
* @param array $bind 参数绑定 * @param array $bind 参数绑定
* @param boolean $fetch 不执行只是获取SQL * @param boolean $fetch 不执行只是获取SQL
* @param boolean $master 是否在主服务器读操作 * @param boolean $master 是否在主服务器读操作
* @param bool $returnPdo 是否返回 PDOStatement 对象 * @param bool|string $returnPdo 是否返回 PDOStatement 对象 如果为字符串则指定类
* @return mixed * @return mixed
* @throws DbBindParamException * @throws DbBindParamException
* @throws PDOException * @throws PDOException
@@ -329,7 +332,7 @@ abstract class Connection
$result = $this->PDOStatement->execute(); $result = $this->PDOStatement->execute();
// 调试结束 // 调试结束
$this->debug(false); $this->debug(false);
return $returnPdo ? $this->PDOStatement : $this->getResult(); return true === $returnPdo ? $this->PDOStatement : $this->getResult($returnPdo);
} catch (\PDOException $e) { } catch (\PDOException $e) {
throw new PDOException($e, $this->config, $this->queryStr); throw new PDOException($e, $this->config, $this->queryStr);
} }
@@ -443,12 +446,28 @@ abstract class Connection
/** /**
* 获得数据集 * 获得数据集
* @access protected * @access protected
* @return array * @param string $class 针对RESULTSET_CLASS 用于指定的类名
* @return mixed
*/ */
protected function getResult() protected function getResult($class = '')
{ {
$result = $this->PDOStatement->fetchAll($this->fetchType); $result = $this->PDOStatement->fetchAll($this->fetchType);
$this->numRows = count($result); $this->numRows = count($result);
switch ($this->resultSetType) {
case Db::RESULTSET_COLLECTION:
// 返回数据集Collection对象
$result = new Collection($result);
break;
case Db::RESULTSET_CLASS:
// 返回指定对象类
if (!empty($class)) {
$result = new $class($result);
}
break;
case Db::RESULTSET_ARRAY:
default:
// 返回二维数组
}
return $result; return $result;
} }

View File

@@ -1322,7 +1322,7 @@ class Query
} }
// 返回结果处理 // 返回结果处理
if (!empty($resultSet)) { if ($resultSet) {
// 数据列表读取后的处理 // 数据列表读取后的处理
if (!empty($options['model'])) { if (!empty($options['model'])) {
@@ -1340,13 +1340,13 @@ class Query
} }
if (!empty($options['with'])) { if (!empty($options['with'])) {
// 预载入 // 预载入
$resultSet = $result->eagerlyResultSet($resultSet, $options['with']); $resultSet = $result->eagerlyResultSet($resultSet, $options['with'], is_class($resultSet) ? get_class($resultSet) : '');
} }
} }
} elseif (!empty($options['fail'])) { } elseif (!empty($options['fail'])) {
throw new DbException('Data not Found', $options, $sql); throw new DbException('Data not Found', $options, $sql);
} }
return Collection::make($resultSet); return $resultSet;
} }
/** /**
@@ -1404,7 +1404,7 @@ class Query
} }
// 数据处理 // 数据处理
if (!empty($result)) { if (!empty($result[0])) {
$data = $result[0]; $data = $result[0];
if (!empty($options['model'])) { if (!empty($options['model'])) {
// 返回模型对象 // 返回模型对象
@@ -1416,7 +1416,7 @@ class Query
} }
if (!empty($options['with'])) { if (!empty($options['with'])) {
// 预载入 // 预载入
$data->eagerlyResult($data, $options['with']); $data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : '');
} }
} }
} elseif (!empty($options['fail'])) { } elseif (!empty($options['fail'])) {

View File

@@ -54,7 +54,8 @@ class Mysql extends Connection
$tableName = str_replace('.', '`.`', $tableName); $tableName = str_replace('.', '`.`', $tableName);
} }
$sql = 'SHOW COLUMNS FROM `' . $tableName . '`'; $sql = 'SHOW COLUMNS FROM `' . $tableName . '`';
$result = $this->query($sql); $pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
if ($result) { if ($result) {
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
@@ -81,7 +82,8 @@ class Mysql extends Connection
public function getTables($dbName = '') public function getTables($dbName = '')
{ {
$sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES '; $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES ';
$result = $this->query($sql); $pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
$info[$key] = current($val); $info[$key] = current($val);

View File

@@ -102,8 +102,9 @@ class Oracle extends Connection
public function getFields($tableName) public function getFields($tableName)
{ {
list($tableName) = explode(' ', $tableName); list($tableName) = explode(' ', $tableName);
$url = "select a.column_name,data_type,DECODE (nullable, 'Y', 0, 1) notnull,data_default, DECODE (A .column_name,b.column_name,1,0) pk from all_tab_columns a,(select column_name from all_constraints c, all_cons_columns col where c.constraint_name = col.constraint_name and c.constraint_type = 'P' and c.table_name = '" . strtoupper($tableName) . "' ) b where table_name = '" . strtoupper($tableName) . "' and a.column_name = b.column_name (+)"; $sql = "select a.column_name,data_type,DECODE (nullable, 'Y', 0, 1) notnull,data_default, DECODE (A .column_name,b.column_name,1,0) pk from all_tab_columns a,(select column_name from all_constraints c, all_cons_columns col where c.constraint_name = col.constraint_name and c.constraint_type = 'P' and c.table_name = '" . strtoupper($tableName) . "' ) b where table_name = '" . strtoupper($tableName) . "' and a.column_name = b.column_name (+)";
$result = $this->query($url); $pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
if ($result) { if ($result) {
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
@@ -129,7 +130,8 @@ class Oracle extends Connection
*/ */
public function getTables() public function getTables()
{ {
$result = $this->query("select table_name from all_tables"); $pdo = $this->linkID->query("select table_name from all_tables");
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
$info[$key] = current($val); $info[$key] = current($val);

View File

@@ -43,7 +43,9 @@ class Pgsql extends Connection
public function getFields($tableName) public function getFields($tableName)
{ {
list($tableName) = explode(' ', $tableName); list($tableName) = explode(' ', $tableName);
$result = $this->query('select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(' . $tableName . ');'); $sql = 'select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(' . $tableName . ');';
$pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
if ($result) { if ($result) {
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
@@ -69,7 +71,9 @@ class Pgsql extends Connection
*/ */
public function getTables($dbName = '') public function getTables($dbName = '')
{ {
$result = $this->query("select tablename as Tables_in_test from pg_tables where schemaname ='public'"); $sql = "select tablename as Tables_in_test from pg_tables where schemaname ='public'";
$pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
$info[$key] = current($val); $info[$key] = current($val);

View File

@@ -40,7 +40,9 @@ class Sqlite extends Connection
public function getFields($tableName) public function getFields($tableName)
{ {
list($tableName) = explode(' ', $tableName); list($tableName) = explode(' ', $tableName);
$result = $this->query('PRAGMA table_info( ' . $tableName . ' )'); $sql = 'PRAGMA table_info( ' . $tableName . ' )';
$pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
if ($result) { if ($result) {
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
@@ -66,9 +68,11 @@ class Sqlite extends Connection
*/ */
public function getTables($dbName = '') public function getTables($dbName = '')
{ {
$result = $this->query("SELECT name FROM sqlite_master WHERE type='table' " $sql = "SELECT name FROM sqlite_master WHERE type='table' "
. "UNION ALL SELECT name FROM sqlite_temp_master " . "UNION ALL SELECT name FROM sqlite_temp_master "
. "WHERE type='table' ORDER BY name"); . "WHERE type='table' ORDER BY name";
$pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
$info[$key] = current($val); $info[$key] = current($val);

View File

@@ -51,13 +51,15 @@ class Sqlsrv extends Connection
public function getFields($tableName) public function getFields($tableName)
{ {
list($tableName) = explode(' ', $tableName); list($tableName) = explode(' ', $tableName);
$result = $this->query("SELECT column_name, data_type, column_default, is_nullable $sql = "SELECT column_name, data_type, column_default, is_nullable
FROM information_schema.tables AS t FROM information_schema.tables AS t
JOIN information_schema.columns AS c JOIN information_schema.columns AS c
ON t.table_catalog = c.table_catalog ON t.table_catalog = c.table_catalog
AND t.table_schema = c.table_schema AND t.table_schema = c.table_schema
AND t.table_name = c.table_name AND t.table_name = c.table_name
WHERE t.table_name = '$tableName'"); WHERE t.table_name = '$tableName'";
$pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
if ($result) { if ($result) {
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
@@ -83,10 +85,12 @@ class Sqlsrv extends Connection
*/ */
public function getTables($dbName = '') public function getTables($dbName = '')
{ {
$result = $this->query("SELECT TABLE_NAME $sql = "SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' WHERE TABLE_TYPE = 'BASE TABLE'
"); ";
$pdo = $this->linkID->query($sql);
$result = $pdo->fetchAll(\PDO::FETCH_ASSOC);
$info = []; $info = [];
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
$info[$key] = current($val); $info[$key] = current($val);

View File

@@ -11,7 +11,6 @@
namespace think\model; namespace think\model;
use think\Collection;
use think\Db; use think\Db;
use think\Exception; use think\Exception;
use think\Loader; use think\Loader;
@@ -115,9 +114,10 @@ class Relation
* @access public * @access public
* @param array $resultSet 数据集 * @param array $resultSet 数据集
* @param string $relation 关联名 * @param string $relation 关联名
* @param string $class 数据集对象名 为空表示数组
* @return array * @return array
*/ */
public function eagerlyResultSet($resultSet, $relation) public function eagerlyResultSet($resultSet, $relation, $class = '')
{ {
/** @var array $relations */ /** @var array $relations */
$relations = is_string($relation) ? explode(',', $relation) : $relation; $relations = is_string($relation) ? explode(',', $relation) : $relation;
@@ -167,7 +167,7 @@ class Relation
if (!isset($data[$result->$localKey])) { if (!isset($data[$result->$localKey])) {
$data[$result->$localKey] = []; $data[$result->$localKey] = [];
} }
$result->__set($relation, Collection::make($data[$result->$localKey])); $result->__set($relation, $this->resultSetBuild($data[$result->$localKey], $class));
} }
} }
break; break;
@@ -196,7 +196,7 @@ class Relation
$data[$result->$pk] = []; $data[$result->$pk] = [];
} }
$result->__set($relation, Collection::make($data[$result->$pk])); $result->__set($relation, $this->resultSetBuild($data[$result->$pk], $class));
} }
} }
break; break;
@@ -205,14 +205,27 @@ class Relation
return $resultSet; return $resultSet;
} }
/**
* 封装关联数据集
* @access public
* @param array $resultSet 数据集
* @param string $class 数据集类名
* @return mixed
*/
protected function resultSetBuild($resultSet, $class = '')
{
return $class ? new $class($resultSet) : $resultSet;
}
/** /**
* 预载入关联查询 返回模型对象 * 预载入关联查询 返回模型对象
* @access public * @access public
* @param Model $result 数据对象 * @param Model $result 数据对象
* @param string $relation 关联名 * @param string $relation 关联名
* @param string $class 数据集对象名 为空表示数组
* @return \think\Model * @return \think\Model
*/ */
public function eagerlyResult($result, $relation) public function eagerlyResult($result, $relation, $class = '')
{ {
$relations = is_string($relation) ? explode(',', $relation) : $relation; $relations = is_string($relation) ? explode(',', $relation) : $relation;
@@ -243,7 +256,7 @@ class Relation
if (!isset($data[$result->$localKey])) { if (!isset($data[$result->$localKey])) {
$data[$result->$localKey] = []; $data[$result->$localKey] = [];
} }
$result->__set($relation, Collection::make($data[$result->$localKey])); $result->__set($relation, $this->resultSetBuild($data[$result->$localKey], $class));
} }
break; break;
case self::BELONGS_TO_MANY: case self::BELONGS_TO_MANY:
@@ -257,7 +270,7 @@ class Relation
if (!isset($data[$pk])) { if (!isset($data[$pk])) {
$data[$pk] = []; $data[$pk] = [];
} }
$result->__set($relation, Collection::make($data[$pk])); $result->__set($relation, $this->resultSetBuild($data[$pk], $class));
} }
break; break;