Vapor文档学习廿二:FLUENT - Relation

Relations可以让两个数据库通过外键进行关联。这在基础的SQL数据库很常见,但是也可以用于NoSQL的数据库中。
Fluent的Relations有以下几种:

  • Parent (BelongsTo)
  • Children (HasMany, HasOne)
  • Siblings (ManyToMany, BelongsToMany)

Parent

一个实体通过给另一个实体外部键关联起来,就构成了父关系(parent)。如下所示:

pets
- id
- owner_id
- name
- type

owner
- id
- name

这里每个pets都可以拥有一个owner。 要从pet访问owner,请调用.parent()。ps:owner将id定义为owner_id作为外键与pets关联起来,那么owner就是petsparent。一个pets有且只有一个owner。(也就是一个儿子有且只有有一个爹)

let pet: Pet = ...
let owner = try pet.parent(pet.ownerId, Owner.self).get()

parent()的参数是外键和parent的类型。

Convenience

为了使查询parent更简单,我们给model添加一个方法:

extension Pet {
    func owner() throws -> Parent {
        return try parent(ownerId)
    }
}

在扩展了Pet类之后,我们不需要再在ownerId前加pet.了。另外,由于返回类型已经确定,所以也不需要Owner.self这个参数了。

Parent类型是一个可查询的对象,也就意味着同样可以使用deletefilterparent进行操作。

try pet.owner().delete()

获取parent则需要调用get():

let owner = try pet.owner().get()

Children

ChildrenParent关系相反,总结之前的例子,也可以通过owner查询pets

let owner: Owner = ...
let pets = owner.children(Pet.self).all()

参数只有child的类型。

Convenience

Parent一样,扩展添加一个查询child的方法:

extension Owner {
    func pets() throws -> Children {
        return try children()
    }
}

返回值中明确了返回类型,所以也不再需要Pet.self这个参数了。
Children也是可查询对象,所以可以调用first()all()filter()等方法。

let coolPets = try owner.pets().filter("type", .in, ["Dog", "Ferret"]).all()

Siblings(兄弟姐妹)

Siblings不同于ParentChild关系,需要Pivot类作为枢纽。
举个例子,假设我们要让我们的pets有多个toys。 但是我们也希望toys能被多种pets共享。 我们需要一个Pivot实体(也就是单独创建一个关联表)。

pets
- id
- type
- owner_id

toys
- id
- name

pets_toys
- id
- pet_id
- toy_id

如你所见,创建了一个实体:pets_toys或者是Pivot

Convenience

Pet添加一个快捷方法:

extension Pet {
    func toys() throws -> Siblings {
        return try siblings()
    }
}

反过来给Toy也添加一个:

extension Toy {
    func pets() throws -> Siblings {
        return try siblings()
    }
}

然后就可以像查询child关系那样去查询了:

let pet: Pet = ...
let toys = pet.toys().all()

下面是创建“多对多”关系的方法:


var toy: Toy = ...                      // Create a new toy
try toy.save()                          // Save the toy to the db

var pet: Pet = ...                      // Create a new pet
try pet.save()                          // Save the pet to the db

// Link them together in the db
var pivot = Pivot(toy, pet)   // Create the relationship
try pivot.save()                        // Save the relationship to the db

Preparation

为了备份通过Pivot建立的关系,只要简单的将这个pivot添加到Dropletpreparations中。

let drop = Droplet()
drop.preparations += [
    Toy.self,
    Pet.self,
    Pivot.self
]

总结:这节主要介绍了表之间的关联关系,以及如何通过关联关系进行数据查询。最后介绍了如何对Pivot进行备份。

你可能感兴趣的:(Vapor文档学习廿二:FLUENT - Relation)