likes
comments
collection
share

TypeORM框架中的实体存储库(EntityManager、Repository)以及常用API

作者站长头像
站长
· 阅读数 13

在看文档前,如果对Find选项和修饰符作用不清楚的,建议先看下Find查询选项修饰符,点击链接即可跳转

Repository

什么是 Repository

使用Repository,可以管理任何实体。 Repository 就像放一个实体存储库的集合的地方,操作仅限于具体实体。

获取存储库getRepository()方法

可以通过getRepository(Entity)访问存储库

语法:getRepository(具体实体) 例如:

import { getRepository } from "typeorm";
import { User } from "./entity/User";

// 将返回与`User`实体相关联的名为`secondConnection`的数据库连接的`Repository`对象
const fff = getRepository(User, "secondConnection")

// 获取`User`实体类的仓库对象
const userRepository = getRepository(User); 
// 在`userRepository`中查找`id`为`1`的用户,将查询结果赋值给`user`变量
const user = await userRepository.findOne(1);
// 修改`user`对象的`name`属性为`"Umed"`
user.name = "Umed";
// 将`user`对象保存到数据库中,返回一个`Promise`对象
await userRepository.save(user);

findOne()方法表示只查找一条记录,返回一个Promise对象。

save()方法可以用于新增或修改数据,如果user对象的id属性不存在,则表示新增数据;如果id属性存在,则表示修改数据。

Repository的常用API

温馨提示:

有删除功能的方法慎用,建议用更新

EntityManagerRepository方法是异步的,需要使用await关键字等待查询操作完成


  • manager - 存储库使用的EntityManager(实体数据)
// 获得实体数据
const manager = repository.manager;
  • metadata - 存储库管理的实体的EntityMetadata

EntityMetadata(实体元数据)是什么? 是指在TypeORM框架中定义实体时,所使用的描述数据的元素集合。每个实体对象都应该有一份元数据来描述它的表名、列名、关系映射等信息。实体元数据是一个包含实体属性、关系、事件、索引等定义的对象,它是使用装饰器或者传统的类定义方式来定义的。

通过实体元数据,TypeORM可以自动创建数据库表、读取和写入数据库表中的数据,并建立实体之间的关系。

// 获取实体的所有数据信息
import { createConnection } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  // 拿到库中的元数据
  const metadata = connection.getMetadata(User);
  console.log(metadata.tableName); // 输出 user 表的名称
  console.log(metadata.columns); // 输出 user 表的所有列
  console.log(metadata.relations); // 输出 user 表的所有关系映射
});
  • queryRunner - EntityManager使用的查询器。

查询器涉及东西太多,举个例子吧!

import { createConnection } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  // 创建查询器
  const queryRunner = connection.createQueryRunner();
  try {
    // 连接数据库
    await queryRunner.connect();
    // 执行查询语句,返回结果
    const result = await queryRunner.query("SELECT * FROM user");
    console.log(result); // 输出查询结果
  } catch (error) {
    console.error(error);
  } finally {
    // 释放`queryRunner`对象
    await queryRunner.release();
  }
});
  • createQueryBuilder - 创建用于构建 SQL 查询的查询构建器
import { createConnection } from "typeorm";
import { User } from "./entity/User";

createConnection().then(async (connection) => {
  const users = await connection
    // 获取`User`实体的`Repository`对象
    .getRepository(User)
    // 创建一个`QueryBuilder`对象,传入`user`作为表的别名
    .createQueryBuilder("user")
    // 添加条件,查询年龄大于18岁的用户
    .where("user.age > :age", { age: 18 })
    // 添加排序规则,以用户姓名为升序排序
    .orderBy("user.name", "ASC")
    // 执行查询
    .getMany();
  console.log(users); // 输出查询结果
});
  • getId - 获取给定实体的主列属性值
// 获取实体的主列属性和值
const userId = repository.getId(user); // userId === 1
  • create - 创建User的新实例
const user = repository.create(); // 和 const user = new User();一样
const user = repository.create({
  id: 1,
  firstName: "Timber",
  lastName: "Saw"
}); 
// 效果和下面的一样
// const user = new User(); 
// user.firstName = "Timber"; 
// user.lastName = "Saw";
  • merge - 将多个实体合并为一个实体,多个元素合并成一个
const user = new User();
repository.merge(user, { firstName: "Timber" }, { lastName: "Saw" }); 
// 和 user.firstName = "Timber"; user.lastName = "Saw";一样
  • save - 保存给定实体或实体数组
import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const user1 = new User()
  user1.name = "张三"
  const UserRepository = connection.getRepository(User);
  // 将user1存储到User表中
  UserRepository.save(user1)
});

如果该实体已存在于数据库中,则会更新该实体。    如果数据库中不存在该实体,则会插入该实体。支持部分更新

  • remove - 删除给定的实体或实体数组
import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const user1 = new User()
  user1.name = "张三"
  const UserRepository = connection.getRepository(User);
  // 将删除User表
  UserRepository.remove(User)
});
  • insert - 插入新实体或实体数组
import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 向User表中插入数据
   awit UserRepository.insert({  
    firstName: "Timber",  
    lastName: "Timber"  
  });
});
  • update - 通过给定的更新选项或实体 ID 部分更新实体

有两种方法来修改数据

方法一:

repository.update(参数一,参数二)

第一个参数是一个对象,包含需要更新的数据的查询条件;第二个参数是一个对象

方法二:

repository.update(主键值,参数二)

第一个参数是实体的主键值;第二个参数是一个对象,包含需要更新的数据

// 方法一:更新了所有`firstName`为`Timber`的用户记录的`firstName`为`Rizzrak`
await repository.update({ firstName: "Timber" }, { firstName: "Rizzrak" });
// 执行 UPDATE user SET firstName = Rizzrak WHERE firstName = Timber

// 方法二:更新了`id`为1的用户记录的`firstName`为`Rizzrak`
await repository.update(1, { firstName: "Rizzrak" });
// 执行 UPDATE user SET firstName = Rizzrak WHERE id = 1
  • delete -根据实体 id, ids 或给定的条件删除实体

-----可以删除一条数据,也可以根据条件,进行批量删除

import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 删除了`id`为1的用户记录
  await UserRepository.delete(1);
  // 删除了`id`为1、2、3的三个用户记录
  await UserRepository.delete([1, 2, 3]);
  // 删除了所有`firstName`为`Timber`的用户记录
  await UserRepository.delete({ firstName: "Timber" });
});
  • find - 查找指定条件的实体

find方法很复杂,查询数据由多个配置项来确定,点击查看详细介绍

import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 查询`id`为 1 的用户记录
  await UserRepository.find(1);
  // 查询 firstName为 "Timber" 的数据
  await UserRepository.find({ firstName: "Timber" });
});
  • findAndCount - 查找指定条件的实体。

会计算统计指定条件匹配的所有实体数量,会忽略分页设置 (skip 和 take 选项)

import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 查询`firstName`为 "Timber" 的用户记录
  const [timbers, timbersCount] = await UserRepository.findAndCount({ firstName: "Timber" });
});

查询结果和数据总数都是通过数组赋值的方式返回,可以用及解构的方式接收使用。在这个例子中,查询结果用变量timbers表示,数据总数用变量timbersCount表示。

  • findByIds - 按 ID 查找多个实体
import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 查询id为 1,2,5 的用户记录
  const users = await UserRepository.findByIds([1,2,5]);
});
  • findOne - 查找匹配某些 ID 或查找选项的第一个实体

注意 :

findOne()方法只会返回一条数据,即使数据库中存在多条符合条件的数据,也只会返回其中的一条数据,如果没有找到,返回undefined

import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 只返回一条数据
  // 查询 id 为 1 的用户记录
  const user = await UserRepository.findOne(1);
  // 查询 firstName 为 Timber 的用户记录
  const timber = await UserRepository.findOne({ firstName: "Timber" });
});
  • findOneOrFail查找匹配某些 ID 或查找选项的第一个实体
import { createConnection,getRepository } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getRepository(User);
  // 只返回一条数据
  // 查询 id 为 1 的用户记录
  const user = await UserRepository.findOneOrFail(1);
  // 查询 firstName 为 Timber 的用户记录
  const timber = await UserRepository.findOneOrFail({ firstName: "Timber" });
});

findOneByOrFail()方法只会返回一条数据,即使数据库中存在多条符合条件的数据,也只会返回其中的一条数据

  • query - 执行原始 SQL 查询
// 执行SQL语句
const rawData = await repository.query(`SELECT * FROM USERS`);
  • clear - 清除给定表中的所有数据
await repository.clear();

EntityManager

使用EntityManager,可以管理(insert, update, delete, load 等)任何实体。 EntityManager 就像放一个实体存储库的集合的地方。

通过getManager()Connection访问实体管理器

import { getManager } from "typeorm";
import { User } from "./entity/User";

const entityManager = getManager(); // 你也可以通过 getConnection().manager 获取
const user = await entityManager.findOne(User, 1);
user.name = "Umed";
await entityManager.save(user);

EntityManager的常用API

EntityManager和Repository使用的API大同小异

下面将展示有不同写法的方法(大部分都是写法的不同,效果功能一样),并介绍两者有哪里不同


最大的区别: EntityManager中的方法,第一个参数是具体实体,Repository的方法则不用

原因: Repository是用getRepository(User)来获取实体,在获取时就已经指定了是哪一个实体;

EntityManager是用getManager()来获取实体,在获取没有指定了是哪一个实体,就需要在方法里面指定实体


  • connection - 使用EntityManager连接
import { getManager } from "typeorm";
import { User } from "./entity/User";

const entityManager = getManager(); 
// 获取`manager`对象所管理的数据库连接
const connection = entityManager.connection;
await entityManager.save(user);
  • insert - 插入新实体或实体数组

Repository对象的insert()方法,该方法用于向数据库中插入一条数据,参数是对象

EntityManager对象的insert()方法,该方法用于向数据库中批量插入数据,参数是数组

import { createConnection,getManager } from "typeorm";
import { User } from "./entity/User";

// 创建数据库
createConnection().then(async (connection) => {
  const UserRepository = connection.getManager();
  // 向User表中插入数据
  await UserRepository.insert(User, [
    {
      firstName: "Foo",
      lastName: "Bar"
    },
    {
      firstName: "Rizz",
      lastName: "Rak"
    }
  ]);
});

如何连接到数据库

Find() 方法数据查询