<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # ORM <p class="uk-article-lead">Pagekit 的對象關系映射工具(Pagekit Object-relational mapper ,ORM)幫助你創建應用程序的模型類,在模型類中每個屬性都被自動映射到了相關數據表的列。你還可以定義你的實體(entities)與 Pagekit 中現有實體之間的關系(比如用戶)</p> ## 設置 ### 創建表 比如在擴展的 `scripts.php` 的 `install` 鉤子中運行以下代碼。了解更多關于創建表的一般信息,查看[數據庫](224140)。 Example: ```php $util = $app['db']->getUtility(); if ($util->tableExists('@forum_topics') === false) { $util->createTable('@forum_topics', function ($table) { $table->addColumn('id', 'integer', ['unsigned' => true, 'length' => 10, 'autoincrement' => true]); $table->addColumn('user_id', 'integer', ['unsigned' => true, 'length' => 10, 'default' => 0]); $table->addColumn('title', 'string', ['length' => 255, 'default' => '']); $table->addColumn('date', 'datetime'); $table->addColumn('modified', 'datetime', ['notnull' => false]); $table->addColumn('content', 'text'); $table->addIndex(['user_id'], 'FORUM_TOPIC_USER_ID'); $table->setPrimaryKey(['id']); }); } ``` ### 定義一個 Model 類 Example: ``` <?php namespace Pagekit\Forum\Model; use Pagekit\Database\ORM\ModelTrait; /** * @Entity(tableClass="@forum_topics") */ class Topic { use ModelTrait; /** @Column(type="integer") @Id */ public $id; /** @Column */ public $title = ''; /** @Column(type="datetime") */ public $date; /** @Column(type="text") */ public $content = ''; /** @Column(type="integer") */ public $user_id; /** * @BelongsTo(targetEntity="Pagekit\User\Model\User", keyFrom="user_id") */ public $user; } ``` 模型(model)是使用 `Pagekit\Database\ORM\ModelTrait` 特性的簡單 PHP類。特性(trait)允許將某些行為包含到類中 - 類似簡單的類的繼承。主要區別在于類可以使用多個特性,但只能從一個類繼承。 **Note** 如果你不熟悉特性,趕緊看一下[PHP 關于特性的官方文檔](http://php.net/manual/en/language.oop5.traits.php). 注釋 `@Entity(tableClass="@my_table")` 將模型與數據表 `pk_my_table` 綁定 (`@` 會自動替換為安裝時填寫的數據表前綴) 注釋的代碼只會在以兩個星號開頭的多行注釋中工作,只有一個星號沒法工作。 ``` // will NOT work: /* @Column */ // will work: /** @Column */ // will work: /** * @Column */ ``` 在類中定義一個屬性時,可以將變量綁定到數據表的列上,在屬性定義代碼上面加上 `/** @Column(type="string") */` 注釋就行。你可以使用由 [Doctrine DBAL](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html) 支持的任意類型。 在模型類中引用的類也必須在數據庫中存在。 ## 關系 表現在數據庫模型中的應用程序數據包含其實例之間的關系。一篇博客文章有與之相關的若干評論,博客文章也恰好歸屬于一個用戶實例。Pagekit ORM 提供了定義這些關系的機制,并且也以程序化的方式來查詢它們。 ### 歸屬關系 用在不同的關系類型上的基礎注釋,即模型屬性上方的 `@BelongsTo` 注釋。在下面的例子中(從博客的 `Post`模型中獲取)我們指定了一個 `$user` 屬性,它被定義用來指向 Pagekit `User` 模型的實例。 `keyFrom` 參數指定哪些源屬性是用來指向用戶 ID的。注意,為了通過一個查詢分辨關系,我們還需要定義相應的 `user_id` 屬性。 Example: ``` /** @Column(type="integer") */ public $user_id; /** * @BelongsTo(targetEntity="Pagekit\User\Model\User", keyFrom="user_id") */ public $user; ``` ### 一對多關系 在這種關系中,單個模型實例被引用到了任意多個其他模型示例。經典的例子是,一篇 `Post` 擁有任意數量的歸屬于它的 `Comment` 實例。 反過來看,一個評論恰好歸屬于一篇 `Post`。 在 `Pagekit\Blog\Model\Post` 中,源自博客包的例子: ``` /** * @HasMany(targetEntity="Comment", keyFrom="id", keyTo="post_id") */ public $comments; ``` 在 `Pagekit\Blog\Model\Comment` 中定義逆向關系: ``` /** @Column(type="integer") */ public $post_id; /** @BelongsTo(targetEntity="Post", keyFrom="post_id") */ public $post; ``` 要查詢模型(Model),可以使用 ORM 類: ``` use Pagekit\Blog\Post; // ... // 獲取文章,不包含相關評論 $posts = Post::findAll(); var_dump($posts); ``` 輸出: ``` array (size=6) 1 => object(Pagekit\Blog\Model\Post)[4513] public 'id' => int 1 public 'title' => string 'Hello Pagekit' (length=13) public 'comments' => null // ... 2 => object(Pagekit\Blog\Model\Post)[3893] public 'id' => int 2 public 'title' => string 'Hello World' (length=11) public 'comments' => null // ... // ... ``` ``` use Pagekit\Blog\Post; // ... // 獲取文章,包括相關評論 $posts = Post::query()->related('comments')->get(); var_dump($posts); ``` 輸出: ``` array (size=6) 1 => object(Pagekit\Blog\Model\Post)[4512] public 'id' => int 1 public 'title' => string 'Hello Pagekit' (length=13) public 'comments' => array (size=0) empty // ... 2 => object(Pagekit\Blog\Model\Post)[3433] public 'id' => int 2 public 'title' => string 'Hello World' (length=11) public 'comments' => array (size=1) 6 => object(Pagekit\Blog\Model\Comment)[4509] ... // ... // ... ``` ### 一對一關系 一對一是非常簡單的關系。一個 `ForumUser` 可能恰好有一個 `Avatar` 指定給它。雖然只是簡單地將關于頭像的所有信息包含在 `ForumUser` 模型中,有時將它們分到不同模型也是在情理之中。 要實現一對一關系,可以在每個模型類中使用 `@BelongsTo` 注釋。 `/** @BelongsTo(targetEntity="Avatar", keyFrom="avatar_id", keyTo="id") */` - `targetEntity`: 模目標模型類 - `keyFrom`: 在這個表中指向關聯模型的外鍵 - `keyTo`: 關聯模型的主鍵 示例模型 `ForumUser`: ```php <?php namespace Pagekit\Forum\Model; use Pagekit\Database\ORM\ModelTrait; /** * @Entity(tableClass="@forum_user") */ class ForumUser { use ModelTrait; /** @Column(type="integer") @Id */ public $id; /** @Column */ public $name = ''; /** @Column(type="integer") */ public $avatar_id; /** @BelongsTo(targetEntity="Avatar", keyFrom="avatar_id", keyTo="id") */ public $avatar; } ``` 示例模型 `Avatar`: ```php <?php namespace Pagekit\Forum\Model; use Pagekit\Database\ORM\ModelTrait; /** * @Entity(tableClass="@forum_avatars") */ class Avatar { use ModelTrait; /** @Column(type="integer") @Id */ public $id; /** @Column(type="string") */ public $path; /** @Column(type="integer") */ public $user_id; /** @BelongsTo(targetEntity="ForumUser", keyFrom="user_id", keyTo="id") */ public $user; } ``` 要確保被關聯的模型包含在查詢結果中,從模型類中獲取 `QueryBuilder` 實例,并在 `related()` 方法中顯式列出關系屬性。 ```php <?php use Pagekit\Forum\Model\ForumUser; use Pagekit\Forum\Model\Avatar; // ... // 獲取所有用戶,包括相關的 $avatar 對象 $users = ForumUser::query()->related('avatar')->get(); foreach ($users as $user) { var_dump($user->avatar->path); } // 獲取所有用戶,包括相關的 $user 對象 $avatars = Avatar::query()->related('user')->get(); foreach ($avatars as $avatar) { var_dump($avatar->user); } ``` ### 多對多關系 有時,一個關系中的兩個模型可能各自都有*許多實例*。比如文章和標簽之間的關系:一篇文章可以有多個指定給它的標簽,同時一個標簽也可以被指定給多篇文章。 下面有一個不同的例子,是討論區論壇中“喜歡的話題”這個場景。一個用戶可以有多個喜歡的話題。一個話題也可以被多個用戶喜歡。 要實現多對多關系,需要一個額外的數據表。表中的每個實體表示從一個 `Topic` 實例到一個 `ForumUser` 實例的連接關系,反之亦然。在數據庫建模時,這被稱為 [聯接表(junction table)](https://en.wikipedia.org/wiki/Associative_entity)。 數據表示例 (比如在 `scripts.php` 中): ``` $util = $app['db']->getUtility(); // 論壇用戶表 if ($util->tableExists('@forum_users') === false) { $util->createTable('@forum_users', function ($table) { $table->addColumn('id', 'integer', ['unsigned' => true, 'length' => 10, 'autoincrement' => true]); $table->addColumn('name', 'string', ['length' => 255, 'default' => '']); $table->setPrimaryKey(['id']); }); } // 話題表 if ($util->tableExists('@forum_topics') === false) { $util->createTable('@forum_topics', function ($table) { $table->addColumn('id', 'integer', ['unsigned' => true, 'length' => 10, 'autoincrement' => true]); $table->addColumn('title', 'string', ['length' => 255, 'default' => '']); $table->addColumn('content', 'text'); $table->setPrimaryKey(['id']); }); } // 聯接表 if ($util->tableExists('@forum_favorites') === false) { $util->createTable('@forum_favorites', function ($table) { $table->addColumn('id', 'integer', ['unsigned' => true, 'length' => 10, 'autoincrement' => true]); $table->addColumn('user_id', 'integer', ['unsigned' => true, 'length' => 10, 'default' => 0]); $table->addColumn('topic_id', 'integer', ['unsigned' => true, 'length' => 10, 'default' => 0]); $table->setPrimaryKey(['id']); }); } ``` 關系本身是在你希望在每個模型類中可以查詢它時定義的。如果指向為特定用戶列出最喜愛的話題,但不列出喜歡了某個給定文章的所有用戶,你只需在一個模型中定義這個關系就行了。下面的例子中, `@ManyToMany` 注釋在兩個模型類中都標注了。 `@ManyToMany` 可以接受這些參數: |參數 | 描述| |---------------- | -----------| |`targetEntity` | 目標模型類| |`tableThrough` | 聯接表的名稱| |`keyThroughFrom` | "from" 方向的外鍵名稱| |`keyThroughTo` | "to" 方向的外鍵名稱| |`orderBy` | (可選)列表的排序| 注釋示例: ```php /** * @ManyToMany(targetEntity="ForumUser", tableThrough="@forum_favorites", keyThroughFrom="topic_id", keyThroughTo="forum_user_id") */ public $users; ``` 模型示例 `Topic`: ```php <?php namespace Pagekit\Forum\Model; use Pagekit\Database\ORM\ModelTrait; /** * @Entity(tableClass="@forum_topics") */ class Topic { use ModelTrait; /** @Column(type="integer") @Id */ public $id; /** @Column */ public $title = ''; /** @Column(type="text") */ public $content = ''; /** * @ManyToMany(targetEntity="ForumUser", tableThrough="@forum_favorites", keyThroughFrom="topic_id", keyThroughTo="forum_user_id") */ public $users; } ``` 模型示例 `ForumUser`: ```php <?php namespace Pagekit\Forum\Model; use Pagekit\Database\ORM\ModelTrait; /** * @Entity(tableClass="@forum_user") */ class ForumUser { use ModelTrait; /** @Column(type="integer") @Id */ public $id; /** @Column */ public $name = ''; /** * @ManyToMany(targetEntity="Topic", tableThrough="@forum_favorites", keyThroughFrom="forum_user_id", keyThroughTo="topic_id") */ public $topics; } ``` 查詢示例: ```php // 在查詢中解決多對多關系 // 獲取特定用戶喜歡的話題 $user_id = 1; $user = ForumUser::query()->where('id = ?', [$user_id])->related('topics')->first(); foreach ($user->topics as $topic) { // } // 獲取喜歡特定話題的所有用戶 $topic_id = 1; $topic = Topic::query()->where('id = ?', [$topic_id])->related('users')->first(); foreach ($topic->users as $user) { // ... } ``` ## ORM 查詢 用給定的 id 獲取模型實例。 ``` $post = Post::find(23) ``` 獲取模型的所有實例。 ``` $posts = Post::findAll(); ``` 使用以上查詢,關系不會擴大到包括相關的實例。在上面的例子中,`Post` 實例不會使它的 `$comments` 屬性被初始化。 ``` // 默認地,相關的對象不會被獲取 $post->comments == null; ``` 這樣做是為性能考慮。默認地,被包含的子查詢都不會執行,這樣就能節省執行時間。所以,如果你需要被關聯的對象,可以在 `QueryBuilder` 上使用 `related()` 方法,并明確地聲明在此查詢中要用到的關系。 所以,要獲取一個 `Post` 實例并包含相關的 `Comment` 實例,你需要構建一個獲取相關對象的查詢。 ``` // fetch all, including related objects $posts = Post::query()->related('comments')->get(); // fetch single instance, include related objects $id = 23; $post = Post::query()->related('comments')->where('id = ?', [$id])->first(); ``` 注意 `find(23)` 是如何被 `->where('id = ?', [$id])->first()` 替代的。這是因為 `find()` 是定義在模型上的方法。然而在第二個例子中,我們擁有一個 `Pagekit\Database\ORM\QueryBuilder` 的實例。 了解更多關于 ORM 查詢和常規查詢的信息,查閱文檔[數據庫](224140)中查詢相關部分。) ## 新建模型實例 你可以在新的模型實例上通過調用 `save()` 方法創建和保存一個新的模型。 ```php $user = new ForumUser(); $user->name = "bruce"; $user->save(); ``` 作為一種選擇,可以在模型類上直接調用 `create()` 方法,并提供一個現有數據的數組來初始化實例。然后調用 `save()` 將實例存儲到數據庫。 ```php $user = ForumUser::create(["name" => "peter"]); $user->save(); ``` ## 修改現有的實例 獲取現有實例,對對象執行任意修改,然后調用 `save()` 方法將這些修改存儲到數據庫。 ```php $user = ForumUser::find(2); $user->name = "david"; $user->save(); ``` ## 刪除現有的實例 獲取現有的實例,并調用 `delete()` 方法將此實例從數據庫中移除。 ```php $user = ForumUser::find(2); $user->delete(); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看