安装和使用

安装和使用

本指南将引导你在 AdonisJS 应用中完成 Lucid 的设置。你将学会如何:

  • 将 Lucid 安装到现有应用中
  • 查看 configure 命令生成的数据库配置
  • 创建并运行你的第一个迁移
  • 构建一个模型并从控制器中查询它
  • 在需要时降级使用原始查询构建器

概述

Lucid 已包含在新的 AdonisJS 应用中,并默认配置为使用 SQLite。如果你的应用是通过 starter kit 创建的,那么你已经拥有一个可用的数据库设置,可以直接跳到创建第一个表

如果你正在将 Lucid 添加到现有的 AdonisJS 应用中,或者之前移除了它现在想重新使用,请按照下面的安装部分操作。对于从一开始就需要 PostgreSQL、MySQL 或其他数据库的应用,请参阅配置指南了解完整的驱动和连接选项。

安装到现有应用中

从 npm registry 安装 Lucid。

npm i @adonisjs/lucid

运行 configure 命令将 Lucid 注册到框架中。--db 标志用于选择数据库驱动,SQLite 是本地验证的最快选项。

terminal
node ace configure @adonisjs/lucid --db=sqlite
  1. adonisrc.ts 中注册 Lucid 服务提供者。

    adonisrc.ts
    export default defineConfig({
    providers: [
    () => import('@adonisjs/lucid/database_provider'),
    ],
    })
  2. adonisrc.ts 中注册 Lucid 命令。

    adonisrc.ts
    export default defineConfig({
    commands: [
    () => import('@adonisjs/lucid/commands'),
    ],
    })
  3. 创建 config/database.ts 并配置所选驱动。

  4. 为所选数据库添加环境变量和验证规则。

  5. 安装所需的数据库驱动。

数据库配置

configure 命令根据你选择的驱动生成 config/database.ts。SQLite 的设置如下所示。

config/database.ts
import env from '#start/env'
import { defineConfig } from '@adonisjs/lucid'
const dbConfig = defineConfig({
connection: 'sqlite',
connections: {
sqlite: {
client: 'better-sqlite3',
connection: {
filename: env.get('DB_DATABASE', 'tmp/db.sqlite3'),
},
useNullAsDefault: true,
migrations: {
naturalSort: true,
paths: ['database/migrations'],
},
},
},
})
export default dbConfig

生成器还会将数据库文件路径添加到你的 .env 文件中。

.env
DB_DATABASE=tmp/db.sqlite3

默认路径将 SQLite 数据库存储在 tmp/ 目录中,该目录随每个 AdonisJS starter kit 提供,因此无需进一步的文件系统设置。

关于连接字符串、多连接、读/写副本、连接池选项和驱动特定设置,请参阅配置指南

创建第一个表

使用 make:migration 命令来生成迁移文件。--create 标志会生成一个创建新表的迁移。

terminal
node ace make:migration posts --create=posts

打开生成的文件,描述 posts 表的列。

database/migrations/1720000000000_create_posts_table.ts
import { BaseSchema } from '@adonisjs/lucid/schema'
export default class extends BaseSchema {
protected tableName = 'posts'
async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.string('title').notNullable()
table.text('body').nullable()
table.timestamp('created_at')
table.timestamp('updated_at')
})
}
async down() {
this.schema.dropTable(this.tableName)
}
}

运行迁移在数据库中创建表。

terminal
node ace migration:run

Lucid 会应用所有待处理的迁移文件,为每个文件打印确认信息,并为现在存在的每个表重新生成一个带类型 schema 类的 database/schema.ts。你的模型将在下一步中继承该 schema 类。

使用模型

Lucid 的主要工作流使用基于类的模型。一个模型将一个 TypeScript 类映射到一个数据库表,从生成的 schema 继承列类型,并让你在数据旁边添加关联关系、生命周期钩子和领域方法。

posts 表生成一个模型。

terminal
node ace make:model Post

生成的模型继承了 posts 表的 schema 类,因此你不需要在模型本身上重新声明列。

app/models/post.ts
import { PostsSchema } from '#database/schema'
export default class Post extends PostsSchema {}

在控制器中使用模型。Post.create() 插入一行并返回模型实例,Post.query() 返回一个限定在 posts 表范围内的带类型查询构建器。

app/controllers/posts_controller.ts
import type { HttpContext } from '@adonisjs/core/http'
import Post from '#models/post'
export default class PostsController {
async store({ request }: HttpContext) {
return Post.create({
title: request.input('title'),
body: request.input('body'),
})
}
async index() {
return Post.query().orderBy('id', 'desc')
}
}

start/routes.ts 中绑定控制器,以便通过 HTTP 调用它。

start/routes.ts
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get('/posts', [PostsController, 'index'])
router.post('/posts', [PostsController, 'store'])

启动开发服务器,发送请求到 POST /posts 来创建你的第一行数据,然后使用 GET /posts 来读取它。现在你已经拥有了一个可用的端到端 Lucid 设置。

只有在需要覆盖生成的 schema 行为时,才直接在模型上定义列,例如自定义序列化、prepareconsume 转换,或带有自定义逻辑的访问器。对于其他所有情况,生成的 schema 类仍然是真相之源。

不使用模型的查询

你也可以直接使用 db 服务来插入和读取行,而无需经过模型。这种方式适用于一次性查询、报表或内部脚本,这些场景中完整的模型机制超出了你的需求。

app/controllers/posts_controller.ts
import type { HttpContext } from '@adonisjs/core/http'
import db from '@adonisjs/lucid/services/db'
export default class PostsController {
async store({ request }: HttpContext) {
const [post] = await db
.table('posts')
.insert({
title: request.input('title'),
body: request.input('body'),
})
.returning(['id', 'title', 'body'])
return post
}
async index() {
return db
.from('posts')
.select('id', 'title', 'body')
.orderBy('id', 'desc')
}
}

请参阅数据库服务指南了解 db 服务的完整入口点。

后续步骤