Select
从表中选择数据。
select($table, $columns)
-
table [string]
表名。
-
columns [array/string]
将要获取的目标列。
select($table, $columns, $where)
-
table [string]
表名。
-
columns [array/string]
将要获取的目标列。
-
where (可选) [array]
用于过滤记录的 WHERE 子句。
select($table, $join, $columns, $where)
-
table [string]
表名。
-
join [array]
表的表关联。如果不需要表连接,请忽略它。
-
columns [array/string]
将要获取的目标列。
-
where (可选) [array]
用于过滤记录的 WHERE 子句。
您可以使用 * 作为列参数来获取所有列,但我们建议提供所有目标列以获得更好的性能和可读性。
$data = $database->select("account", [ "user_name", "email" ], [ "user_id[>]" => 100 ]); // $data = array( // [0] => array( // "user_name" => "foo", // "email" => "foo@bar.com" // ), // [1] => array( // "user_name" => "cat", // "email" => "cat@dog.com" // ) // ) foreach($data as $item) { echo "user_name:" . $item["user_name"] . " - email:" . $item["email"] . "
"; } // 选择所有列。 $data = $database->select("account", "*"); // 选择一列。 $data = $database->select("account", "user_name"); // $data = array( // [0] => "foo", // [1] => "cat" // )
使用回调遍历获取
从数据库获取数据时,数据将首先作为数组变量加载到内存中,然后输出回前端。如果从数据库获取大量数据,内存将会耗尽。当将回调闭包函数 ($data) {} 作为 select() 的最后一个参数传递时,它将立即输出每个数据,而无需将其加载到内存中。这对于加载大量数据将具有更好的性能。
$database->select("account", ["name"], function ($data) { echo $data["name"]; }); $database->select("account", [ "name" ], function ($data) { echo $data["name"]; });
性能基准
从 MySQL 数据库中获取 1,000、5,000 和 20,000 个不同的名称数据,并输出它。通过 memory_get_usage() 获取内存使用情况。
方法 1 | 方法 2 |
$database->select("account", ["name"], function ($data) { echo $data["name"]; }); |
$data = $database->select("account", ["name"]); foreach ($data as $item) { echo $item["name"]; } |
方法 1 | 方法 2 | |
1,000 条记录 | 789 KB | 1.2 MB |
5,000 条记录 | 1.1 MB | 3.3 MB |
20,000 条记录 | 2.26 MB | 11.1 MB |
表连接
SQL JOIN 子句可以合并两个表之间的行。Medoo 为 JOIN 子句提供了简单的语法。
[>] ==> LEFT JOIN [<] ==> RIGHT JOIN [<>] ==> FULL JOIN [><] ==> INNER JOIN
$database->select("post", [ // 这是表关联参数,告诉您要连接的表之间的关联性。 "[>]account" => ["author_id" => "user_id"] ], [ "post.title", "account.city" ]);
表 post 中的行 author_id 等于表 account 中的行 user_id。
"[>]account" => ["author_id" => "user_id"] LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"
表 post 中的行 user_id 等于表 album 中的行 user_id。如果两个表中的行名相同,这是声明关联性的快捷方式。
"[>]album" => "user_id" LEFT JOIN "album" USING ("user_id")
post.user_id 等于 photo.user_id 且 post.avatar_id 等于 photo.avatar_id。像上面一样,两个表中有两个或更多相同的行。
"[>]photo" => ["user_id", "avatar_id"] LEFT JOIN "photo" USING ("user_id", "avatar_id")
如果您想用不同的值连接同一个表,您必须为表分配一个别名。
"[>]account (replier)" => ["replier_id" => "user_id"] LEFT JOIN "account" AS "replier" ON "post"."replier_id" = "replier"."user_id"
您可以通过在列前添加表名来引用先前连接的表。
"[>]account" => ["author_id" => "user_id"], "[>]album" => ["account.user_id" => "user_id"] LEFT JOIN "account" ON "post"."author_id" = "account"."user_id" LEFT JOIN "album" ON "account"."user_id" = "album"."user_id"
多重条件
"[>]account" => [ "author_id" => "user_id", "album.user_id" => "user_id" ] LEFT JOIN "account" ON "account"."author_id" = "account"."user_id" AND "album"."user_id" = "account"."user_id"
附加条件
"[>]comment" => [ "author_id" => "user_id", "AND" => [ "rate[>]" => 50 ] ] LEFT JOIN "comment" ON "account"."author_id" = "comment"."user_id" AND "rate" > 50
使用 Raw 对象连接
"[>]account" => Medoo::raw("ON= ") LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"
数据映射
自定义输出数据结构 - 包装数据的键名与列本身无关,并且是多维的。
$data = $database->select("post", [ "[>]account" => ["user_id"] ], [ "post.content", "userData" => [ "account.user_id", "account.email", "meta" => [ "account.location", "account.gender" ] ] ], [ "LIMIT" => [0, 2] ]); echo json_encode($data);
[{ content: "Hello world!", userData: { user_id: "1", email: "foo@example.com", meta: { location: "New York", gender: "male" } } }, { content: "Hey everyone", userData: { user_id: "2", email: "bar@example.com", meta: { location: "London", gender: "female" } } }]
索引映射
将列设置为列参数的第一个键名,结果将以此名称为索引。
$data = $database->select("post", [ "user_id" => [ "nickname", "location", "email" ] ]);
[ 10: { nickname: "foo", location: "New York", email: "foo@example.com" }, 12: { nickname: "bar", location: "New York", email: "bar@medoo.in" } ]
数据类型声明
设置输出数据的类型。
// 支持的数据类型: [String | Bool | Int | Number | Object | JSON] // [String] 是所有输出数据的默认类型。 // [Object] 是由 serialize() 解码的 PHP 对象数据,将会被 unserialize() // [JSON] 是有效的 JSON,将会被 json_decode() $data = $database->select("post", [ "[>]account" => ["user_id"] ], [ "post.post_id", "profile" => [ "account.age [Int]", "account.is_locked [Bool]", "account.userData [JSON]" ] ]); echo json_encode($data);
[{ post_id: "1", profile: { age: 20, is_locked: true, userData: ["foo", "bar", "tim"] } }, { post_id: "2", profile: { age: 25, is_locked: false, userData: ["mydata1", "mydata2"] } }]
// 在数据库中存储一个对象,然后取回它。 class Foo { var $bar = "cat"; public function __wakeup() { $this->bar = "dog"; } } $object_data = new Foo(); $database->insert("account", [ "data" => $object_data ]); $data = $database->select("account", [ "data [object]" ]); echo $data[0]["data"]->bar; // 对象的 __wakeup 函数将被调用并更新值。 // 所以输出将是 "dog"。 "dog"
别名
您可以使用别名作为新的列或表名,而不是原始名称。这对于表连接以防止名称冲突很有用。
$data = $database->select("account", [ "user_id", "nickname (my_nickname)" ]); // $data = array( // [0] => array( // "user_id" => "1", // "my_nickname" => "foo" // ), // [1] => array( // "user_id" => "2", // "my_nickname" => "bar" // ) // )
$data = $database->select("post (content)", [ "[>]account (user)" => "user_id", ], [ "content.user_id (author_id)", "user.user_id" ]); // $data = array( // [0] => array( // "author_id" => "1", // "user_id" => "321" // ), // [1] => array( // "author_id" => "2", // "user_id" => "322" // ) // )
SELECT "content"."user_id" AS author_id, "user"."user_id" FROM "post" AS "content" LEFT JOIN "account" AS "user" USING ("user_id")
Distinct
要向列添加 distinct 关键字,您可以在任何顺序的列名前放置 @。
$data = $database->select("account", [ "id", "name", // 带有 @ 符号的 location 将会弹出到顶部。 "@location" ]);
SELECT DISTINCT "location","id","name" FROM "account"
要获取带有 distinct 的计数,您可以将其与 raw 对象一起使用。
$data = $database->select("account", [ "unique_locations" => Medoo::raw("COUNT(DISTINCT)") ]);
SELECT COUNT(DISTINCT "location") AS "unique_locations" FROM "account"