Query
类贯穿Fluent交互的整个过程,无论是使用.find()
查询数据还是将数据保存到数据库,都要用到Query
。
Querying Models
遵守Model协议的类型都会有一个静态方法.query()
。
let query = try User.query()
这就创建了一个.query()
。
No Database
使用 try
调用.query()
方法是因为如果Model对应的数据库不存在就会抛出异常。
User.database = drop.database
当Model
作为preparation
的时候这个属性会自动添加。
Fileter
大多数查询都会进行数据过滤(条件查询)。
let smithsQuery = try User.query().filter("last_name", "Smith")
上面是一个简单的equals
查询。如你所见,可以将filter()
链接在query()
之后。
除了equals
之外,还有很多其他的Filter.Comparison
。
let over21 = try User.query().filter("age", .greaterThanOrEquals, 21)
Scope
过滤条件的套用:
let coolPets = try Pet.query().filter("type", .in, ["Dog", "Ferret"])
这里只会返回Dog
或Ferret
类型的数据。相反则是notIn
。
Contains
部分匹配的过滤条件也可以使用:
let statesWithNew = try State.query().filter("name", contains: "New")
Retrieving
有两种方法进行查询。
All
all()
进行整体匹配,返回所有满足查询条件的[Model]
数组。下面的例子会返回所有age>21
的user
。
let usersOver21 = try User.query().filter("age", .greaterThanOrEquals, 21).all()
First
first()
会匹配第一个满足查询条件的数据,返回的是Model?
类型,下面返回的是一个user
。
let firstSmith = try User.query().filter("last_name", "Smith").first()
Union
联合查询,即使用其他Model
辅助查询。结果会返回[Model]
或者Model?
。
let usersWithCoolPets = try User.query()
.union(Pet.self)
.filter(Pet.self, "type", .in, ["Dog", "Ferret"])
上面就是用User
集合与Pet
集合联合查询,返回所有拥有宠物dog或ferret的User
。
Keys
调用union
方法查询的前提是被查询的表具有和辅助表关联的外部标识。(也就是两个表有关联的字段。)
上例中有如下关联:
users
- id
pets
- id
- user_id
外部标识的key
可以通过重载提供给union
。
Raw Queries
由于Fluent专注于与Model
进行交互,因此每个Query
需要一个模型类。 如果要进行不基于Model
的原始数据库查询,则应使用底层Fluent驱动程序来执行此操作。
if let mysql = drop.database?.driver as? MySQLDriver {
let version = try mysql.raw("SELECT @@version")
}
<b>总结:</b>本节讲了如何进行数据查询以及过滤查询的方法。最后节后也说明了如何进行基于sql语句的原始查询方法。