数据库

Mirage 数据层的核心是一个简单的内存数据库。该数据库存储 Mirage 的所有初始状态,然后您的路由处理程序在使用应用程序时访问和修改该状态。

数据库允许 Mirage 模拟生产服务器,使您能够在应用程序中编写完整的动态功能。

大多数 Mirage 代码不会直接访问数据库,而是通过 Mirage 的 ORM 与其交互。我们将在这些指南的下一节中介绍 ORM。

现在,让我们学习数据库的基础知识,这样您就可以自信地直接与它交互,即使大多数代码最终都使用 ORM。

基本用法

Mirage 的数据库实际上只是一个 JavaScript 对象,它有一些关于它的约定。它可以通过您的 server 实例访问

let server = createServer()

server.db // {} the db is empty

您可以调用它的 loadData 来用一些数据填充它

server.db.loadData({
  movies: [
    { title: "Interstellar" },
    { title: "Inception" },
    { title: "Dunkirk" },
  ],
})

loadData 接受一个对象,其键对应于数据库表,其值表示数据库记录的数组。

数据库会自动为新记录分配 ID(您也可以提供自己的 ID)。我们可以使用 MongoDB 风格的 API 访问数据

// Get all movies
server.db.movies // [ { id: '1', title: 'Interstellar' }, { id: '2', title: 'Inception' }, { id: '3', title: 'Dunkirk' } ]

// Get the first movie
server.db.movies[0] // { id: '1', title: 'Interstellar' }

// Insert a new movie
server.db.movies.insert({ title: "The Dark Knight" })

Mirage 有一个 seeds 方法,这是一个在开发过程中将一些初始数据放入服务器的约定位置。您可以在其中调用数据库上的 loadData

createServer({
  seeds(server) {
    server.db.loadData({
      movies: [
        { title: "Interstellar" },
        { title: "Inception" },
        { title: "Dunkirk" },
      ],
    })
  },
})

真正的力量来自于在路由处理程序中访问数据库。您可以使用 schema 参数获取它

this.get("/movies", (schema, request) => {
  return schema.db.movies
})

这个路由处理程序现在会响应 Mirage 数据库在请求时所有的数据。这意味着,如果您从以下数据开始;

[
  { "id": "1", "title": "Interstellar" },
  { "id": "2", "title": "Inception" },
  { "id": "3", "title": "Dunkirk" }
]

但随后编写一个新的路由处理程序,将数据插入到 movies 集合中

this.post("/movies", (schema, request) => {
  let attrs = JSON.parse(request.requestBody)

  return schema.db.movies.insert(attrs)
})

并使用您的应用程序创建一个新电影,您的应用程序第二次向 /movies 发出 GET 请求时,它将使用新的数据库数据进行响应

[
  { "id": "1", "title": "Interstellar" },
  { "id": "2", "title": "Inception" },
  { "id": "3", "title": "Dunkirk" },
  { "id": "4", "title": "The Dark Knight" }
]

正如您将在下一节中了解到的,大多数路由处理程序将与 schema ORM 对象交互,而不是低级数据库对象,但了解数据库的存在仍然很重要,以备不时之需。

您直接使用数据库的最常见地方是在您的测试中,您可以在其中通过 server.db 访问它。断言 Mirage 数据库的状态以验证您的应用程序的网络请求是否发送了正确的数据可能很有用。

test("I can create a movie", async function (assert) {
  await visit("/movies/new")
  await fillIn(".title", "The Dark Knight")
  await click(".submit")

  assert.dom("h2").includesText("New movie saved!")
  assert.equal(server.db.movies[0].title, "The Dark Knight")
})

您可以在 API 参考中查看数据库 API 的其余部分。


接下来,让我们了解一下 Mirage 的 ORM。