关联查询

    • 用户拥有更多个文章
    • 文章拥有多个标签
    • 文章属于一个用户
    • 文章标签关联记录属于一个标签和一篇文章

    拥有关系查询语法:

    $row->has($name, $foreignKeyOrCallback = null, $callback = null, $storeKey = null)

    • name 目标表名
    • foreignKeyOrCallback 外键名称或者回调函数,如果不传或传入的是一个函数则外键默认为:表名+_id user_id
    • callback 回调函数,可以自己追加一些查询条件
    • storeKey 存储键名 默认为表明,同一个关联表多次查询但是条件不同需要自定义存储键名

    属于关系查询语法:

    • name 目标表名
    • foreignKeyOrCallback 外键名称或者回调函数,如果不传或传入的是一个函数则外键默认为:表名+_id user_id
    • callback 回调函数,可以自己追加一些查询条件
    • storeKey 存储键名 默认为表明,同一个关联表多次查询但是条件不同需要自定义存储键名

    返回值说明:

    ->has('table') 方法返回的是一个 Cabal\DB\Rows 对象里,也是一个所有元素都是 Cabal\DB\Row 的数组。

    ->belongs('table') 方法返回的是一个 Cabal\DB\Row 对象。

    返回:

    1. {
    2. "id": 1,
    3. "username": "Cabal",
    4. "articleList": [
    5. {
    6. "id": 1,
    7. "user_id": 1,
    8. "status": 1,
    9. "title": "PHP 教程",
    10. "content": "...",
    11. "created_at": "2018-01-02 246:01:0",
    12. "tagList": [
    13. "PHP",
    14. "教程"
    15. ]
    16. },
    17. {
    18. "id": 2,
    19. "user_id": 1,
    20. "status": 1,
    21. "title": "PHP 简介",
    22. "content": "...",
    23. "created_at": "2018-01-03 199:00:0",
    24. "tagList": [
    25. "简介"
    26. ]
    27. },
    28. "id": 3,
    29. "user_id": 1,
    30. "status": 1,
    31. "title": "PHP 安装",
    32. "content": "...",
    33. "created_at": "2018-01-04 30:00:00",
    34. "tagList": [
    35. "PHP",
    36. "安装"
    37. ]
    38. },
    39. {
    40. "id": 4,
    41. "user_id": 1,
    42. "status": 0,
    43. "title": "草稿",
    44. "content": "...",
    45. "created_at": "2018-01-01 05:00:00",
    46. "tagList": [
    47. ]
    48. }
    49. ]
    50. }

    上面的代码调用了以下的查询语句:

    多个用户的文章查询示例:

    1. $userList = $db->table('user')->select(['id', 'username'])->rows();
    2. foreach ($userList as $user) {
    3. foreach ($user->has('article') as $article) {
    4. $tagList = [];
    5. foreach ($article->has('article_tag') as $articleTag) {
    6. $tag = $articleTag->belongs('tag');
    7. $tagList[] = $tag->name;
    8. }
    9. $article->tagList = $tagList;
    10. $articleList[] = $article->jsonSerialize();
    11. }
    12. }
    13. return $userList;

    上面的代码调用了以下的查询语句:

    1. [
    2. {
    3. "sql": "SELECT id,username FROM `user`",
    4. "params": [
    5. ],
    6. },
    7. {
    8. "sql": "SELECT `article`.* FROM `article` WHERE user_id IN (?, ?)",
    9. "params": [
    10. 1,
    11. 2
    12. ],
    13. },
    14. {
    15. "sql": "SELECT `article_tag`.* FROM `article_tag` WHERE article_id IN (?, ?, ?, ?, ?)",
    16. "params": [
    17. 1,
    18. 2,
    19. 3,
    20. 4,
    21. 5
    22. ],
    23. },
    24. {
    25. "sql": "SELECT `tag`.* FROM `tag` WHERE id IN (?, ?, ?, ?)",
    26. "params": [
    27. 1,
    28. 4,
    29. 3,
    30. 2
    31. ],
    32. }
    33. ]
    1. 没有使用 JOIN 查询,因为 JOIN 查询性能可能没有简单查询效率高,尤其是数据表大了之后,
    2. 合并了查询,查询多篇文章的标签时,自动将多条查询转化成 WHERE IN 查询,减少查询次数,提高查询效率。
    3. 即使多次调用 和->belongs('table') 获取关联数据也不会产生多次的数据查询!