Vapor 2.0 - 模型(Model)

前往 Vapor 2.0 - 文檔目錄

模型是數(shù)據(jù)庫中Swift數(shù)據(jù)的展示。因此,它們對于大多數(shù)Fluent的api來說都是至關(guān)重要的。

本指南概述了與模型相關(guān)的協(xié)議需求和方法。

再瞧瞧
請參閱入門指南,了解如何使用模型。

增刪改查(CRUD)

模型有幾種基本的創(chuàng)建、讀取、更新和刪除的方法。

保存(Save)

將實體持久化到數(shù)據(jù)存儲中并設(shè)置id屬性。

let pet = Pet(name: "Spud", age: 2)
try pet.save()

查找(Find)

找到提供的標識符或返回nil的模型。

guard let pet = try Pets.find(42) else {
    throw Abort.notFound
}
print(pet.name)

刪除(Delete)

如果實體以前被獲取或保存,則從數(shù)據(jù)存儲中刪除該實體。

try pet.delete()

全部(All)

為該模型返回所有實體。

for pet in try Pets.all() {
    print(pet.name)
}

計數(shù)(Count)

返回該模型的所有實體的計數(shù)。

let count = try Pets.count()

數(shù)據(jù)塊(Chunk)

返回為該模型的所有實體提供一個提供的大小的數(shù)組。

這是一種解析大型數(shù)據(jù)集的所有模型的好方法。

try Pets.chunk(20) { pets in
    //
}

查詢(Query)

為這個Model創(chuàng)建一個Query實例。

let query = try Pet.makeQuery()

要了解關(guān)于復雜查詢的更多信息,請參見查詢(query)部分。

時間戳(Timestamps)

要向您的模型添加時間戳,只需繼承Timestampable

extension User: Timestampable { }

您可以在任何模型實例上訪問更新(updated at)和創(chuàng)建(created at)。

user.updatedAt // Date?
user.createdAt // Date?

當對時間戳數(shù)據(jù)進行過濾或排序時,您可以使用來自類的時間戳鍵。

let newUsers = try User
    .makeQuery()
    .filter(User.createdAtKey, .greaterThan, ...)
    .all()

如果有定制的需要,還可以覆蓋時間戳鍵。

extension User: Timestampable {
    static var updatedAtKey: String { return "custom_updated_at" }
    static var createdAtKey: String { return "custom_created_at" }
}

遷移(Migration)

Timestampable的模型將自動創(chuàng)建并更新在數(shù)據(jù)庫創(chuàng)建(database create)調(diào)用期間添加的鍵。

如果您需要手動將Timestampable添加到現(xiàn)有的模型中,那么您可以在遷移中使用date()方法。

database.modify(User.self) { builder in
    builder.date(User.createdAtKey)
    builder.date(User.updatedAtKey)
}

軟刪除(Soft Delete)

“軟刪除”是一種“刪除”模型,從所有獲取和更新查詢到流暢,但實際上并不是從數(shù)據(jù)庫中刪除模型。軟刪除的模型也可以恢復。

要使您的模型具有可軟的可刪除性,只需將其繼承SoftDeletable

extension User: SoftDeletable { }

一旦您的模型是軟的,所有調(diào)用delete()的調(diào)用將在標記中設(shè)置刪除,而不是實際刪除模型。

要恢復模型,請調(diào)用.restore()。要從數(shù)據(jù)庫中刪除一個模型,請調(diào)用.forceDelete()

如果您有定制的需要,也可以覆蓋軟刪除鍵。

extension User: SoftDeletable {
    static var deletedAtKey: String { return "custom_deleted_at" }
}

包含刪除(Including Deleted)

當一個模型被軟刪除時,它不會被任何用流利的查詢構(gòu)建器所做的查詢所影響。

要包含軟刪除的模型,例如,如果您想要恢復它們,請使用query builder中的.withSoftDeleted()方法。

let allUsers = try User.makeQuery().withSoftDeleted().all()

生命周期(Lifecycle)

您可以連接到模型的軟刪除事件。

extension User: SoftDeletable {
    func willSoftDelete() throws { ... }
    func didSoftDelete() { ... }
    func willForceDelete() throws { ... }
    func didForceDelete() { ... }
    func willRestore() throws { ... }
    func didRestore() { ... }
}

筆記
在一個will鉤子上投擲,將阻止動作的發(fā)生。

遷移(Migration)

SoftDeletable模型將自動在數(shù)據(jù)庫創(chuàng)建(database create )調(diào)用期間添加一個刪除鍵。
如果您需要手動添加一個現(xiàn)有模型的SoftDeletable,您可以在遷移中使用date()方法。

database.modify(User.self) { builder in
    builder.date(User.deletedAtKey, optional: true)
}

便利(Convenience)

斷言存在(Assert Exists)

模型的標識符屬性是可選的,因為模型可能還沒有被保存。

如果模型還沒有通過調(diào)用assertExists()來保存,那么您可以獲得標識符或者拋出錯誤。

let id = try pet.assertExists()
print(id) // not optional

生命周期(Life Cycle)

可以在您的模型上實現(xiàn)以下生命周期方法,以便將其連接到內(nèi)部操作。

/// Called before the entity will be created.在創(chuàng)建實體之前調(diào)用。
/// Throwing will cancel the creation.投擲將會取消創(chuàng)建。
func willCreate() throws

/// Called after the entity has been created.在創(chuàng)建實體之后調(diào)用。
func didCreate()

/// Called before the entity will be updated.在實體將被更新之前調(diào)用。
/// Throwing will cancel the update.投擲將會取消更新。
func willUpdate() throws

/// Called after the entity has been updated.在實體更新后調(diào)用。
func didUpdate()

/// Called before the entity will be deleted.在實體被刪除之前調(diào)用。
/// Throwing will cancel the deletion.投擲將取消刪除。
func willDelete() throws

/// Called after the entity has been deleted.該實體已被刪除。
func didDelete()

筆記
拋出一個willFoo()方法將取消操作。

下面是實現(xiàn)didDelete方法的一個示例。

final class Pet: Model {
    ... 

    func didDelete() {
        print("Deleted \(name)")
    }
}

實體(Entity)

實體是模型遵循的基本的流暢協(xié)議。在保存、獲取或刪除模型時,它負責提供數(shù)據(jù)庫或查詢可能需要的所有信息。

名字(Name)

這個模型的唯一關(guān)系名稱。也用于內(nèi)部存儲。例如:Pet=“pet”。

這種價值通常不應該過分夸大。

final class Pet: Model {
    static let name = "pet"
}

實體(Entity)

這個模型的復數(shù)關(guān)系名稱。用作集合或表名。

例如:Pet=“pets”。

如果您的模型的表名是非標準的,那么這個值應該被覆蓋。

final class Pet: Model {
    static let entity = "pets"
}

ID類型(ID Type)

用于本地和外id鍵的標識符類型。

例如:uuid,integer,等等。

如果數(shù)據(jù)庫中的某個特定模型使用了不同的ID類型,那么該值應該被過度使用。

final class Pet: Model {
    static let idType: IdentifierType = .uuid
}

還可以使用配置在數(shù)據(jù)庫級別上覆蓋這一層。
Config/fluent.json

{
    "idType": "uuid"
}

或用編程。

drop.database?.idType = .uuid

關(guān)鍵的命名約定(Key Naming Convention)

用于外id鍵、表名等的命名傳輸。

例如:snake_case與camelCase。

如果數(shù)據(jù)庫中的某個特定模型使用不同的鍵命名約定,那么該值應該被覆蓋。

final class Pet: Model {
    static let keyNamingConvention = .snake_case
}

還可以使用配置在數(shù)據(jù)庫級別上覆蓋這一層。
Config/fluent.json

{
    "keyNamingConvention": "snake_case"
}

或用編程。

drop.database?.keyNamingConvention = .snake_case

ID Key

與該實體的標識鍵對應的列的名稱。

默認的是“database.driver.idKey”,然后是“id”

final class Pet: Model {
    static let idKey = "id"
}

外來的ID KEY(Foreign ID Key)

當從其他表或集合引用時,指向該實體的id的列的名稱。

例如:“foo_id”。

final class Pet: Model {
    static let foreignIdKey = "pet_id"
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內(nèi)容