使用nestjs搭建个人博客(三)—— 操作数据库

1,546 阅读4分钟

记录使用nest.js搭建个人博客的一些学习分享,通过使用和笔记希望可以让自己学的更扎实,对知识点的掌握更熟练。上次已经连接好了数据库,今日就来操作数据库来完成我的DAO层。

起步

前面记录到,在使用TypeORM操作数据库时大部分是通过对象的方式来操作的,而不是直接通过编写sql来操作。当然,这不是绝对的,在某些复杂的场景下,也是会要构建sql语句来完成数据库的操作。

这里我用到操作数据库的方式是:TypeORM的实体类仓库管理器开操作,这种方式简单方便,其他的方式也可以访问官网去了解。

在nest中使用

之前说过,在nest中,我们直接在构造函数中通过这样写就能获取实体的仓库存储器:

constructor(
    @InjectRepository(Article)
    private readonly articleRepository: Repository<Article>
) {}

现在,就可以通过访问this.articleRepository来操作数据库了。

查询数据库

当我们获得了实体类的仓库存储器后,就可以通过它来调用对应的API来操作数据库了,接下来就记录几种常用的操作方式。

find

find方法文档介绍的非常详细,可以去官网看一下,find方法直接接受一个conditionns参数,这个参数里面包含若干查询条件,比如常用的如下。

where

表示查询条件,例如:

article.find({ where: { title: 'Hello Nest' } })

如上,我们就可以找出titleHello Nest的数据,如果没有则返回undefined
另外,where还可以搭配内置运算符使用,例如:

article.find({ where: { title: Like('%Hello%') } })

上面将查出所有title包含Hello的数据。

select

表示需要查询的那些字段,没有的字段将会是默认值,例如:

article.find({ select: ['title', 'desc'] });

这样的查询结果,返回的实体类中只有titledesc属性中有值。

relations

这个表示关联查询,当我们的表有关联时(一对多,多对一,多对多,该知识点可以看你官网),就可以通过使用该属性非常方便的获取关联对象,例如:

article.find({ relations: ['category'] });

当查询到对应的文章时,会把该文章对应的分类一并查出,并赋值到文章实体类对应的属性中去(这里就是category: Category)。

skit和take

这两个主要用于分页,take表示取多少条,而skip表示跳过多少条,例如这里我要完成一个每页取10条的分页查询就可以这样实现:

articleRepository.find({
    skip: (page - 1) * size,
    take: size
})

findOne

findOne文档没怎么记录,通过在findOne的声明文件中,我们可以找到这样一个方法:

findOne(id?: string | number | Date | ObjectID, options?: FindOneOptions<Entity>): Promise<Entity | undefined>;

可以发现有两个可选参数,第一个是id,第二个是一个FindOneOptions的泛型接口,先不管这个。
通过以上定义我们就可以知道: 这个方法是应该是通过id来查询对应表的一条数据的,其返回是一个Promise对象或者是一个undefined

findAndCount

这个方法一般也是作为分页时用,它除了具有find方法的功能外,还能查出对应条件的总记录数量(不受takeskip分页的影响),并且返回一个数组:第一个参数为find查询的记录数,第二个为总记录数量,例如:

const [articles, total] = articleRepository.findAndCount();
// articles: Article[]
// total: number

添加/修改数据库

添加和修改数据库的记录,这里我推荐一个API,就是:save
这个API既可以添加数据,也可以修改数据,其使用区别就是: 当传入实体类有对应的id时,则为保存数据;没有id时则为添加数据,例如:

const article = new Article();
article.title = '新增文章';
articleRepository.save(article); // 添加了一条数据,假设生成了id=1的记录
article.id = 1;
article.title = '修改标题';
articleRepository.save(article); // id=1的记录标题被改为了“修改标题”

并且,save方法是很强大的,当有对应关系的对象存在时,也会给关联的实体对象对应的表添加数据。例如:

// article和tag是多对多关系,因此除了article表还有一张tag表和一张记录tag和article的关联表
const article = new Article();
article.title = '新增文章';
const tag = new Tag();
tag.title = '标签';
article.tags = [tag];
articleRepository.save(article); // 添加了一条数据,并且tag表和关联表也添加了对应数据

删除数据

删除数据非常简单,通过delete方法即可实现,使用方式有以下三种:

  1. 直接传入一个number:表示删除对应id的数据;
  2. 传入一个number[]:表示删除对应数组内的所有id的数据;
  3. 传入一个对象:按条件删除,例如:
articleRepository.delete({
    title: '标题'
});

总结

以上就是通过实体类的仓库存储器操作数据库的几种简单方式,了解这些方式后就可以比较轻松的做一些基本的CRUD业务。

其实操作数据库,还有其他的方式,甚至更强大,例如:EntityManagerQuery Builder这两种,感兴趣可以看一下。

To Be Continue...