跳到主要内容位置

如何在 NestJS 中设置 SQLite3 数据库连接

峰华

最近在做一个 React + Nest.js 的练习小项目,因为目标成品应用是作为桌面端来使用的,所以数据的保存就成了一个问题,是保存到文件中还是数据库中还是其它的存储系统里?后来研究了一下,觉得存放在 sqlite3 数据库中比较合适,因为它管理起来简单,数据库的数据都保存在一个指定的文件里。

info

之所以使用 Nest.js 编写后端,是为了后面为 Web 端和 APP 端提供数据,至于能不能坚持到开发到这种地步就不好说了,暂时先不管这个,总之多学习、多练习没坏处。

Nest.js 是什么?

Nest.js 是基于 Node.js 的企业级开发框架,跟 Java 的 Spring 差不多,提供了 RESTful API、数据库、验证鉴权、GraphQL、微服务、WebSocket 等常见的企业级业务组件,可以说覆盖了一个应用的所有业务需求。

Nest.js 的编程语言主要是 TypeScript,不过也可以使用原生 JavaScript,但是要利用 Nest.js 的所有特性,推荐使用 TypeScript。另外基于类型的语言在开发的时候更方便调试。

Sqlite3 是什么?

Sqlite3 是一个小型的、全功能的关系型数据库(RDBMS),支持完整的 SQL 语言。Sqlite3 经常在移动设备中作为数据存储服务,因为它占的内存比较小,并且容易管理数据,使用 Sqlite3 创建的数据库都保存在一个文件中,这样不同的 App 可以使用自己的数据库文件,管理自己的数据。

在 Nest.js 中配置 Sqlite3

Nest.js 集成了 TypeOrm 框架,支持多种数据库。

安装依赖库

要配置 Sqlite3,我们首先需要安装 @nestjs/typormtypeormsqlite3 这几个依赖库,分别是 nest.js 的 typeorm 集成库、typeorm 官方库和 sqlite3 的连接驱动。

npm install --save @nestjs/typeorm typeorm sqlite

配置连接信息

之后我们在 app.module.ts 中,导入 TypeOrmModule,然后在 imports 数组中,调用它的 forRoot() 方法来配置数据库信息:

import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
imports: [
TypeOrmModule.forRoot({
type: 'sqlite',
database: 'db.sql',
autoLoadEntities: true,
synchronize: true,
}),
],
})

这里的配置项的含义是:

  • type:数据库类型,这里使用的是 sqlite,可以选择 mysql、postgres、sqlite、mssql 等。
  • database:Sqlite3 数据库文件的存放路径,这里放到项目的根目录下的 db.sql 文件中。
  • autoLoadEntities:自动加载实体,也就是数据库表和 TypeScript 的映射类。
  • synchronzie:设置为 true 后,项目启动的时候会根据实体的配置,自动创建 sqlite3 的数据库表。

测试

我们用创建用户的逻辑来测试一下连接。Nest.js 提供的命令行工具能方便的创建一组 CRUD 代码,在项目根目录下使用下面这条命令:

nest g res users

这样就创建了和 users 用户相关的模块。users/entities/user.entity.ts 中的 User 类就是用户实体,它的代码是这样的:

user.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
}

这里就简单的配置了 id 和 username 用户名两个属性,id 为自动生成。

users.service.ts 中,使用构造函数依赖注入的方式,把 UserRepository 注入进来,这样可以让我们使用 repository 来操作数据库:

users.service.ts

@Injectable()
export class UsersService {
constructor(
@InjectRepository(User) private usersRepository: Repository<User>,
) {}
}

然后在 create() 方法中,调用 repository 的 save() 方法,把用户信息保存到数据库中:

users.service.ts
  create(createUserDto: CreateUserDto) {
return this.usersRepository.save(createUserDto);
}

这里使用了 CreateUserDto 类,这里简单的介绍一下,DTO 是数据传输对象(Data Transfer Obejct),是用于在网络上传输数据的,例如前端发送过来的数据,使用 dto 接收,后端产生的数据使用 dto 发送,dto 里可以自定义属性,这样可以把实体类中的属性进行增减,以避免不必要的数据泄露(例如密码)。

那么我们的 CreateUserDto 是用来接收前端传递进来的用户信息的,因为我们的 User 中的 id 是自动生成的,所以我们只需要一个 username 属性,那么把 users/dot/create-user.ts 中的代码改一下,添加username 属性:

create-user.ts
export class CreateUserDto {
username: string;
}

最后在 users.module.ts 中,使用 imports 导入 User 实体,这样才能被 TypeOrm 发现并自动加载:

users.module.ts
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}

再检查 app.module.ts 中使用否在 imports 里导入了 UserModule,这个应该在运行 nest g res users 的时候自动加载了:

app.module.ts
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'sqlite',
database: 'db.sql',
autoLoadEntities: true,
synchronize: true,
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

现在,启动一下项目,运行:

npm run start:dev

然后使用 postman 或者其它 api 工具,发送一个 post 请求到 http://localhost:3000/users 上,并附上一个测试的 json 对象:

{
"username": "test"
}

这个时候,如果没有报错,那么这个新创建的用户,就添加进数据库中了。可以使用图形化的 Sqlite3 客户端 DB Browser for Sqlite,打开 db.sql 文件,来看一下数据是否插入成功。

小结

好了,这个就是在 nest.js 中配置 sqlite3 的方法,主要是:

  • 安装依赖。
  • 在 App.module.ts 中调用 TypeOrmModule.forRoot() 方法配置连接信息。

你学会了吗?如果觉得本文有帮助请分享给更多人看,感谢!