Nodejs编程-typeorm实体和实体关系

DataMapper和ActiveRecord两种模式:

        两种模式是如何组织增删改查代码的不同模式

        Active Record:

        在模型本身内定义所有查询方法,并使用模型方法保存、删除和加载对象。

        所有 active-record 实体都必须扩展BaseEntity类,BaseEntity具有标准Repository的大部分方法。

import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;


  static findByName(firstName: string, lastName: string) {
    return this.createQueryBuilder("user")
      .where("user.firstName = :firstName", { firstName })
      .andWhere("user.lastName = :lastName", { lastName })
      .getMany();
  }
}

        this.createQueryBuilder("user") 创建数据库查询对象

        Data Mapper

        实体只是定义了相应的属性,并且可能有一些简单的方法。

        可以在单独类中定义所有查询方法

const userRepository = connection.getRepository(User);

        通过getRepository()函数获取repository的对象

也可以通过继承Repository类:

        

import { EntityRepository, Repository } from "typeorm";
import { User } from "../entity/User";

@EntityRepository()
export class UserRepository extends Repository<User> {
  findByName(firstName: string, lastName: string) {
    return this.createQueryBuilder("user")
      .where("user.firstName = :firstName", { firstName })
      .andWhere("user.lastName = :lastName", { lastName })
      .getMany();
  }
}

Repository类提供了createQueryBuilder()函数

const userRepository = connection.getCustomRepository(UserRepository);
const timber = await userRepository.findByName("Timber", "Saw");

而使用的时候还是需要使用connection.getCustomRepository(UserRepository),不如 connection.getRepository(User); 简单。但是更加规范

总结:active record适合小项目;data mapper适合大项目

创建连接:

        createConnection()

        createConnections()

        connectionManager:(适用动态创建连接的需求)

        const connectionManager = getConnectionManager();

                      const connection = connectionManager.create() // 连接管理器

                      connection.connect()

                                   

注意,createConnection在新的版本里已经被舍弃,使用DataSource()

使用连接:

        getConnection().manager : 对应createConnection()

        const defaultConnection = getConnectionManager().get("default");-> 对应createConnections()

        getManager()

        getRepository(User)

建立连接选项:

        支持不同的持久化存储,type字段可以指定,指定后需要查询对应存储终端对应的字段配置

        支持主从模式:所有模式更新和写入操作都使用master服务器执行。 find方法或select query builder执行的所有简单查询都使用随机的slave实例。

        但是也可以指定查询也是master

        connection API:

                connection.connect()

                connection.close()

                connection.getRepository(User): 获取给定实体的repository,后面用返回的对象进行增删改查

                connection.query(`SELECT * FROM USERS`): 执行sql语句

                connection.createQueryBuilder():创建查询器,查询器不绑定表

                connection.createQueryRunner():管理和使用单个真实数据库连接的查询运行器。返回的对象可以connect(),也可以release()

                const manager: EntityManager = connection.manager; 实体管理器

        

        主要概念:

                实体对应的repository

                查询器:QueryBuilder

                查询运行器: 管理连接

                连接管理器:connectionManager.get("default");

实体:

        @PrimaryGeneratedColumn("uuid")自增主键/自增uuid

        @Column() 可传参

                @Column("int")

                @Column({ type: "int" })

                @Column("varchar", { length: 200 })        

                @Column({ type: "int", length: 200 })

                @Column({
                        type: "varchar",
                        length: 150,
                        unique: true,
                })

        其他配置字段:

        type ,name, length, width, onUpdate, nullable, update, select, default, primary,(同@PrimaryColumn) ,unique , comment, precision, scale, zerofill(unsigned), charset, collation, enum, asExpression , generatedType,hstoreType

        mysql/mariadb的列类型:

        inttinyintsmallintmediumintbigintfloatdoubledecdecimalnumericdatedatetimetimestamptimeyearcharvarcharnvarchartexttinytextmediumtextbloblongtexttinyblobmediumbloblongblobenumjsonbinarygeometrypointlinestringpolygonmultipointmultilinestringmultipolygongeometrycollection

        @PrimaryColumn()

        @OneToMany()

        @ManytoOne()

        @ManyToMany()

        @JoinColumn()

        @OneToOne

实体关系:
        一对一:
class User{
    @OneToOne(()=>Profile)
    @JoinColumn()
    profile:Profile
}

        @OneToOne添加到profile并将目标关系类型指定为Profile

  @JoinColumn,这是必选项并且只能在关系的一侧设置。 设置@JoinColumn一方,表将包含一个"relation id"和目标实体表的外键。上面会在User表里生成profileId的外键

        关联关系查询:

        

const userRepository = connection.getRepository(User);
const users = await userRepository.find({ relations: ["profile"] });

        或者:

const users = await connection
  .getRepository(User)
  .createQueryBuilder("user")
  .leftJoinAndSelect("user.profile", "profile")
  .getMany();

     

         单向关系和双向关系:

                单向是仅在一侧与关系装饰器的关系

                双向是与关系两侧的装饰者的关系。

        一对多/多对一:

                @OneToMany():

                        @OneToMany关系中省略@JoinColumn,除非你需要自定义关联列在数据库中的名称

                        

                @ManyToOne():

        

                @OneToMany必须搭配@ManyToOne使用

        

     多对多:

              @ManyToMany()

              @JoinTable()

        JoinTable会生成中间的关联表,表的列都是主键,且是外键。表的名字是表1名+字段名+表2名

        多对多也区分单向关系和双向关系

        eager:

                eager是什么:原意是热切的,渴求的。在这里可以理解关联关系会自动携带上,省去特殊指定是左关联查询。

                eager只能在find()函数起作用,QueryBuilder则会被禁用。

                内部默认使用leftJoinAndSelect来加载

                Eager 的关系只能用于关系的一方,在关系的两边使用eager:true是不允许的。

 @ManyToMany(type => Category, category => category.questions, {
eager: true
})
        Lazy关系:

                延迟加载

                这是非标准技术,而且在 TypeORM 中被认为是实验性的。

                想拥有延迟加载的关系,你必须使用 promises

    

@ManyToMany(type => Category, category => category.questions)
@JoinTable()
categories: Promise<Category[]>;

        

const question = await connection.getRepository(Question).findOne(1);
const categories = await question.categories;

        加载lazy关系中的数据,使用await

实体关系加载

        使用relations:

const users = await connection.getRepository(User).find({ relations: ["profile", "photos", "videos"] });

          使用QueryBuilder和innerJoinAndSelect,leftJoinAndSelect等:

        

const user = await connection
  .getRepository(User)
  .createQueryBuilder("user")
  .leftJoinAndSelect("user.profile", "profile")
  .leftJoinAndSelect("user.photos", "photo")
  .leftJoinAndSelect("user.videos", "video")
  .getMany();

        外键约束:

                createForeignKeyConstraints

@ManyToOne(type => Person, {
        createForeignKeyConstraints: false
    })
    person: Person;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值