美文网首页
Vapor 2.0 - 查询(Query)

Vapor 2.0 - 查询(Query)

作者: 韩云智VL | 来源:发表于2017-08-10 11:23 被阅读0次

    前往 Vapor 2.0 - 文档目录

    Fluent的查询构建器提供了一个创建复杂数据库查询的简单界面。在Query类本身(不包含原始查询)是通过Fluent的与数据库通信的唯一方法。

    构造(Make)

    您可以从任何模型类创建一个新的查询构建器。

    let query = try Post.makeQuery()
    

    您还可以从实例创建查询。如果您需要使用特殊的数据库连接(如事务处理(transactions))来保存或更新模型,这一点尤其有用。

    guard let post = try Post.find(42) else { ... }
    post.content = "Updated"
    let query = try post.makeQuery(conn).save()
    

    获取(Fetch)

    您有多个选项用于获取查询的结果。

    全部(All)

    最简单的选项.all()返回与查询相关的所有行。

    let users = try User.makeQuery().filter(...).all()
    

    首先(First)

    你也可以用.first()只获取第一行。

    let user = try User.makeQuery().filter(...).first()
    

    Fluent会自动将结果限制为1,以提高查询的性能。

    数据块(Chunk)

    如果要从数据库中获取大量的模型,则使用.chunk()可以帮助通过一次获取数据块来减少查询所需的内存量。

    User.makeQuery().filter(...).chunk(32) { users in
        print(users)
    }
    

    过滤器(Filter)

    过滤器允许您选择想要修改或获取的数据子集。有三种不同类型的过滤器。

    比较(Compare)

    比较过滤器在数据库中的模型和提供的值之间进行比较。

    try query.filter("age", .greaterThanOrEquals, 21)
    

    你也可以使用运算符。

    try query.filter("age" >= 21)
    
    案例Case 运算符Operator 类型Type
    .equals == Equals
    .greaterThan > Greater Than
    .lessThan < Less Than
    .greaterThanOrEquals >= Greater Than Or Equals
    .lessThanOrEquals <= Less Than Or Equals
    .notEquals != Not Equals
    .hasSuffix Has Suffix
    .hasPrefix Has Prefix
    .contains Contains
    .custom(String) Custom

    提示
    您可以省略比较类型.equals,例如,query.filter("age", 23)

    子集(Subset)

    您还可以根据一组数据中的字段进行筛选。

    try query.filter("favoriteColor", in: ["pink", "blue"])
    

    或者相反。

    try query.filter("favoriteColor", notIn: ["brown", "black"])
    

    组(Group)

    默认情况下,所有的查询过滤器都是与(AND)逻辑连接的。您可以在您的查询中创建一组过滤器,这些过滤器是与(AND)或或(OR)逻辑一起连接的。

    try query.or { orGroup in
        try orGroup.filter("age", .greaterThan, 75)
        try orGroup.filter("age", .lessThan, 18)
    }
    

    这将导致SQL类似于以下内容:

    SELECT * FROM `users` WHERE (`age` > 75 OR `age` < 18);
    

    .and()也是可用的,以防您需要用嵌套了一个或(OR)的与(AND)来切换回连接过滤器。

    复杂示例(Complex Example)
    let users = try User
        .makeQuery()
        .filter("planetOfOrigin", .greaterThan, "Earth")
        .or { orGroup in
            orGroup.and { andGroup in
                andGroup.filter("name", "Rick")
                andGroup.filter("favoriteFood", "Beer")
            }
            orGroup.and { andGroup in
                andGroup.filter("name", "Morty")
                andGroup.filter("favoriteFood", "Eyeholes")
            }
        }
        .all()
    

    这将导致SQL类似于以下内容:

    SELECT * FROM `users`
        WHERE `planetOfOrigin` = 'Earth' AND (
               (`name` = 'Rick' AND `favoriteFood` = 'Beer')
            OR (`name` = 'Morty' AND `favoriteFood` = 'Eyeholes')
        )
    

    注意
    请记住,组的AND / OR逻辑仅适用于组内添加的过滤器。过滤器组外的所有过滤器将由AND连接。

    原始(Raw)

    原始过滤器可用于通过不应参数化的值进行过滤。

    try query.filter(raw: "date >= CURRENT_TIMESTAMP")
    

    不同(Distinct)

    要仅从数据库中选择不同的模型,请添加.distinct()到您的查询中。

    try query.distinct()
    

    限制/偏移(Limit / Offset)

    要限制或偏移查询,请使用该.limit()方法。

    try query.limit(20, offset: 5)
    

    排序(Sort)

    要对查询的结果进行排序,请使用该.sort()方法。

    try query.sort("age", .descending)
    

    您可以通过链接您的.sort()调用一次对多个列进行排序。

    try query.sort("age", .descending).sort("shoe_size")
    

    加入(Join)

    您可以将两个模型表连接在一起,如果要通过另一个模型的属性过滤一个模型,这将非常有用。例如,假设你有一个属于Departments的Employees表。你想知道哪个部门包含已经完成了十年服务的员工。

    首先,使用.join()部门查询中的方法将其与Employee表一起加入。接下来你链接.filter()到查询。请记住,您需要将“已连接”模型显式传递给过滤器,否则Fluent将尝试在“基本”模型上过滤。

    let departments = try Department.makeQuery()
      .join(Employee.self)
      .filter(Employee.self, "years_of_service" >= 10)
    

    Fluent将为您提供关系领域,但您也可以使用baseKeyjoinedKey方法参数指定它们,baseKey“base”模型(Department)上的标识符字段在哪里,并且joinedKey是“加入”模型的外键字段(员工)涉及“基地”模式。

    提示
    Fluent支持内部和外部连接; 使用调用.join(kind: .outer, MyModel.self)

    原始(Raw)

    如果您需要执行查询构建器不支持的查询,则可以使用原始查询。

    try drop.database?.raw("SELECT @@version")
    

    您也可以使用给定模型的数据库。

    User.database?.raw("SELECT * FROM `users`")
    

    除了为查询数据库提供了一个更具表达性的接口外,查询构建器还采取了一些措施,通过自动清除输入来增加安全性。因此,可以尝试使用查询类来执行原始查询。

    相关文章

      网友评论

          本文标题:Vapor 2.0 - 查询(Query)

          本文链接:https://www.haomeiwen.com/subject/awacrxtx.html