Vapor3初探——使用Fluent查询数据

Vapor升级到Vapor3的时间恰巧赶上WWDC,本来想从美国回来就开始写一些关于Vapor3的文章,但是WWDC信息量太大了,直到现在才转过来写一点关于Vapor的东西。

这篇文章主要介绍如何使用Fluent查询数据,后面我会补上如何配置相关的教程。

Fluent为我们提供了一个Model类, MySQLModel、 PostgreSQLModel、SQLiteModel均继承自这个类。在Model的一个extension中,Flunt为我们提供了一个query方法并返回 QueryBuilder<Self.Database, Self>

下面,我们再看看这个QueryBuilder:

QueryBuilder<Self.Database, Self>

这个QueryBuilder会含有Model的类型,数据库类型,利用这些信息来连接数据库进行查询。

现在有了这个QueryBuilder了,下面就可以利用它来进行查询操作了:

为了简化对问题的理解,这里提供一个最简单的Model来验证:

import FluentMySQL
import Vapor

/// A single entry of a Todo list.
final class Todo: Codable {
    /// The unique identifier for this `Todo`.
    var id: Int?

    /// A title describing what this `Todo` entails.
    var title: String

    /// Creates a new `Todo`.
    init(id: Int? = nil, title: String) {
        self.id = id
        self.title = title
    }
}


extension Todo: MySQLModel { }

/// Allows `Todo` to be used as a dynamic migration.
extension Todo: Migration { }

/// Allows `Todo` to be encoded to and decoded from HTTP messages.
extension Todo: Content { }

/// Allows `Todo` to be used as a dynamic parameter in route definitions.
extension Todo: Parameter { }

可以看到这里的Todo类只含有一个id和title,而id由mysql数据库自动生成,只需要传入一个title则可以添加一条记录。

查询所有记录

Todo.query(on: req).all()

查询title为'work'的记录

try Todo.query(on: req).filter(\.title == "work" ).all()

查询title不为'work'的记录

try Todo.query(on: req).filter(\.title != "work" ).all()

查询id大于5的记录

try Todo.query(on: req).filter(\.id > 5 ).all()

查询id小于5的记录

try Todo.query(on: req).filter(\.id < 5 ).all()

查询id大于等于5的记录

try Todo.query(on: req).filter(\.id >= 5 ).all()

查询id小于等于5的记录

try Todo.query(on: req).filter(\.id <= 5 ).all()

查询id为 5、7、11的数据

try Todo.query(on: req).filter(\.id ~~ [5, 7, 11]).all()

查询id不为 5、7、11的数据

try Todo.query(on: req).filter(\.id !~ [5, 7, 11]).all()

模糊查询

查询title前缀为‘work’的数据

Todo.query(on: req).filter(\.title, .like, "work%").all()

查询title后缀为‘work’的数据

Todo.query(on: req).filter(\.title, .like, "%work").all()

查询title包含‘work’的数据

Todo.query(on: req).filter(\.title, .like, "%work%").all()

如果只查询一条数据

Todo.query(on: req).filter(\.title, .like, "%work%").first()

如果什么都查不出来,则会返回nil

其实模糊查询也有提供类似于 ==, !=, >, <这样的操作符,但是经过测试并没有达到比较好的效果,所以这里的demo只是展示目前我测试可用的方法,如果未来能够支持的更好,我会再补充。

更多查询方法:

《SQL》库中的GenericSQLBinaryOperator包含sql中需要的操作符,这里贴出部分源码一看究竟:

/// See `SQLSerializable`.
    public func serialize(_ binds: inout [Encodable]) -> String {
        switch self {
        case ._add: return "+"
        case ._bitwiseAnd: return "&"
        case ._bitwiseOr: return "|"
        case ._bitwiseShiftLeft: return "<<"
        case ._bitwiseShiftRight: return ">>"
        case ._concatenate: return "||"
        case ._divide: return "/"
        case ._equal: return "="
        case ._greaterThan: return ">"
        case ._greaterThanOrEqual: return ">="
        case ._lessThan: return "<"
        case ._lessThanOrEqual: return "<="
        case ._modulo: return "%"
        case ._multiply: return "*"
        case ._notEqual: return "!="
        case ._subtract: return "-"
        case ._and: return "AND"
        case ._or: return "OR"
        case ._in: return "IN"
        case ._notIn: return "NOT IN"
        case ._is: return "IS"
        case ._isNot: return "IS NOT"
        case ._like: return "LIKE"
        case ._glob: return "GLOB"
        case ._match: return "MATCH"
        case ._regexp: return "REGEXP"
        case ._notLike: return "NOT LIKE"
        case ._notGlob: return "NOT GLOB"
        case ._notMatch: return "NOT MATCH"
        case ._notRegexp: return "NOT REGEXP"
        }
    }

我们可以在filter中选择适用的操作符。

Order

查询结果可以给一个order进行升序和降序排序

Todo.query(on: req).sort(\.id, .ascending).all()
Todo.query(on: req).sort(\.id, .descending).all()

Union?

目前vapor3配套的Flunt3还没有union功能,并且官方文档和源代码中并未找到union相关的方法,相信不久就会添加相关的特性,还是耐心等待,如果一旦添加了这样的方法,我会第一时间更新。

总结

vapor3的查询还是和vapor2有着比较大的差异的,之前vapor2的一个Model一统江湖的特点在vapor3上也没有得到体现,目前各个子模块也都还在开发中,希望会越来越好用吧。

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1nhel12vro8mw

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

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,789评论 2 89
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    X先生_未知数的X阅读 15,937评论 3 118
  • 落花聽雨阅读 330评论 13 7
  • 在重男轻女的年代,我是被放养的模式长大的,每个人都很忙,忙到除了给我吃穿,别的都顾不上了。 我每天一万个为什么无人...
    孤诣的花田半亩阅读 228评论 1 3
  • 来到邹容烈士纪念碑,四周是静悄悄的。这份静与邹容烈士短暂却炽热的一生形成鲜明的对比。 “革命!革命!得之则生,不得...
    simkey阅读 442评论 0 2