Vapor 2.0 - 数据库(Database)

前往 Vapor 2.0 - 文档目录

Fluent数据库负责管理与底层数据存储的连接,并向您选择的实现特定驱动程序发送查询。

驱动(Drivers)

默认情况下,Fluent包括内存和SQLite驱动程序。有几个驱动程序可用于添加到您的Vapor应用程序。

可用(Available)

类型Type 键Key 包Package 类Class 官方Official
Memory memory Fluent Provider Fluent.MemoryDriver Yes
SQlite sqlite Fluent Provider Fluent.SQLiteDriver Yes
MySQL mysql MySQLProvider MySQLDriver.Driver Yes
PostgreSQL postgresql PostgreSQLProvider PostgreSQLDriver.Driver No
MongoDB N/A MongoProvider N/A No

单击提供程序包以获取有关如何使用它的更多信息。

您可以在GitHub上搜索可用的Vapor数据库提供程序列表。

Droplet

您可以从Droplet访问数据库。

drop.database // Database?

准备(Preparations)

大多数数据库(如SQL数据库)需要在存储模型之前创建模型。为您的模型添加准备将允许您在应用程序引导时准备数据库。

extension User: Preparation {
    /// Prepares a table/collection in the database准备数据库中的表/集合
    /// for storing Users存储用户
    static func prepare(_ database: Database) throws {
        try database.create(self) { builder in
            builder.id()
            builder.string("name")
            builder.int("age")
        }
    }

    /// Undoes what was done in `prepare`撤消在“prepare”中所做的工作
    static func revert(_ database: Database) throws {
        try database.delete(self)
    }
}

以上准备语句的结果与SQL类似如下:

CREATE TABLE `users` (`id` INTEGER PRIMARY KEY NOT NULL, `name` TEXT NOT NULL, `age` INTEGER NOT NULL)

创建完准备后,将其添加到Config的prepratations数组中。

config.preparations.append(User.self)

创建(Create)

在创建和修改数据库时可以使用以下方法。

方法Method 类型Type
id 主标识符Primary Identifier
foreignId 外来识别码Foreign Identifier
int 整数Integer
string 字符串String
double Double
bool Boolean
bytes 数据Data
date 日期+时间Date + Time

您可以在其中的构建器上使用任何这些方法.create()。

try database.create(self) { builder in
    builder.double("latitude")
    builder.double("longitude")
}

外键(Foreign Keys)

外键自动添加.foreignId()。要手动添加外键,请使用该 .foreignKey方法。

try database.create(self) { builder in
    builder.foreignKey("user_id", references: "id", on: User.self)
}

要禁用自动外键,在Config/fluent.json文件中设置autoForeignKeys为false 。

{
    "autoForeignKeys": false
}

修饰(Modifier)

可以使用.modify()属性修改现有模式。所有的方法.create() 也可以在这里。

try database.modify(self) { builder in
    builder.string("name")
    builder.delete("age")
}

迁移(Migrations)

其他时候,您可能希望在迁移到新版本或执行一般清理时对数据集进行一些修改。

struct DeleteOldEntries: Preparation {
    static func prepare(_ database: Database) throws {
        try Log.makeQuery().filter(...).delete()
    }

    ...
}

运行(Run)

您的准备工作将在每次运行应用程序时运行。您可以运行您的准备工作,而无需启动您的服务器:

vapor run prepare

还原(Revert)

使用还原方法撤消在prepare方法中所做的任何工作。

extension User: Preparation {
    ...


    static func revert(_ database: Database) throws {
        try database.delete(self)
    }
}

你可以通过调用以下方式来运行反转:

vapor run prepare --revert

这将恢复最新的一批准备工作。要还原整个数据库,请运行以下命令:

vapor run prepare --revert --all

日志(Log)

记录查询是找到应用程序优化并追踪错误的好方法。

记录查询的最简单方法是启用登录fluent.json文件。
Config/fluent.json

{
    ...,
    "log": true,
    ...
}

这将发出所有数据库查询的信息级日志。

自定义(Custom)

您还可以挂接到数据库的查询记录回调以执行自定义逻辑。

drop.database?.log = { query in
    print(query)
}

您可以log为数据库上的属性分配一个闭包。任何时候运行查询,将使用QueryLog包含描述语句和运行时间的字符串的对象来调用闭包。

处理(Transactions)

事务处理允许您将多个查询分组到一个单独的工作单元中。如果任何一个查询遇到问题,整个事务将被回滚。

drop.database?.transaction { conn in
    try user.pets.makeQuery(conn).delete()
    try user.makeQuery(conn).delete()
}

如果调用此方法,不支持事务处理的驱动程序将抛出错误。

您可以使用该.makeQuery(_: Executor)方法创建将在提供给关闭的连接上运行的查询。

警告
您必须使用到闭包提供的连接,以便在事务处理中包含您想要包含的查询

索引(Indexes)

索引是从可以非常有效地搜索的表中选择的数据列的副本。

您可以通过调用.index()将它们添加到数据库

try database.index("name", for: User.self)

您可以通过调用.deleteIndex()删除它们

try database.deleteIndex("name", for: User.self)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容