typeorm-入门

简述

typeorm是一个数据库orm框架,在nestjs官网中有提到,可以充分发挥利用typescript的特性,当然也支持js其中涉及的概念包括

  • DataSource 数据源,Connection 连接数据库
  • Entity 实体,实体类映射数据库表
  • Relation 关系,定义实体类之间的关系,也就是数据库表之间的关系,一对一,多对一,多对多。
  • Entity Manager和Repository,Entity Manager可以管理创建连接时配置的所有实体,而Repository只能操作对应的实体,两个的api几乎的差不多的
  • QueryBuilder,用来创建更复杂的sql查询,灵活度比较高。

使用typeorm cli快速创建项目

全局安装typeorm
typeorm cli的相关命令,可以快速测试初始化项目,生成实体等等

npm install typeorm -g

初始化项目

typeorm init --name MyProject 

安装连接数据库驱动包,这里以msyql为2,安装msyql2

npm install mysql2

创建连接

import "reflect-metadata"
import { DataSource } from "typeorm"

export const AppDataSource = new DataSource({
  type: "mysql",
  host: "localhost",
  port: 3306,
  username: "root",
  password: "zhuang",
  database: "typeorm_test",// 连接的数据库
  synchronize: true,// 开发过程使用,可以同步修改表结构,生产切忌使用。
  logging: true,// 打印输出sql语句
  connectorPackage: "mysql2",// 驱动包
  entities: ["./**/entity/*.ts"],// 指定entity文件,也可以是实体数组,[User]
  migrations: [],
  subscribers: []
})

定义实体Entity

使用typeorm的装饰器定义实体
装饰器列表

快速成实体

typeorm entity:create -n User
typeorm entity:create src/entity/HelloWorld # 快速生成实体类

实体装饰器

  • @Entity(),@Entity({name:“指定表名”}) ,声明该类是实体类,对应表,表名默认是类名 Class 的小写下划线分割。
@Entity()
@Entity("user")
@Entity({
	name: "users",// 表名
    engine: "MyISAM", // 数据库引擎
    database: 'example_dev',// 数据库
    synchronize: false,// 是否同步更该表结构
    orderBy: {// 查询时的默认排序
        name: "ASC",
        id: "DESC"
    }
})

在这里插入图片描述

  • @ViewEntity(),视图实体,不会对应表
@ViewEntity({ 
    expression: `
        SELECT "post"."id" "id", "post"."name" AS "name", "category"."name" AS "categoryName"
        FROM "post" "post"
        LEFT JOIN "category" "category" ON "post"."categoryId" = "category"."id"
    `
})
export class PostCategory {}

列装饰器

  • @Column(),用来定义实体对应表列,默认对应的列名就是实体的属性名,可以配置,属性的数据类型没有显示指定的话,typeorm会根据ts的类型自动推断,在mysql中,string - varchar(255), boolean - tinyint, number - int,Date - datetime(6)
  • @PrimaryGeneratedColumn(), 相当于@Column({primary:true})具体的列装饰器都是固定了一些配置的装饰器.
  • @CreateDateColumn(),自动插入
  • @UpdateDateColumn(),自动更新
@Entity("users")
export class User {
    @Column({ primary: true }) // 配置主键, @PrimaryGeneratedColumn("uuid"),配置uuid主键
    id: number;

    @Column({ type: "varchar", length: 200, unique: true })// 配置数据库中具体类型,长度,唯一
    firstName: string;

    @Column({ nullable: true })// 配置是否为空
    lastName: string;

    @Column({ default: false })// 配置默认值,boolen默认类型被转换为 tinyint, false 对应 0,true 对应 1
    isActive: boolean;
    
	@CreateDateColumn() // 创建时自动插入
    createdDate: Date;
    
	@UpdateDateColumn() // 更新时自动更新
    updatedDate: Date;

	
}

关系装饰器

指定表之间的关系,默认配置会生成物理外键,可以通过配置RelationOptions{createForeignKeyConstraints:false},不生成外键约束。一般该配置位于装饰器的最后一个参数,如下配置:

/**
 * 描述表之间关系的配置
 */
export interface RelationOptions {
    /**
     * 配置不同表之间插入或更新时,相关的对象怎么配置,cascade:true 表示级联,如 user.roles, 当save的时候,把关联的roles实体也保存或者更新
     * If set to true then it means that related object can be allowed to be inserted or updated in the database.
     * You can separately restrict cascades to insertion or updation using following syntax:
     *
     * cascade: ["insert", "update", "remove", "soft-remove", "recover"] // include or exclude one of them
     */
    cascade?: boolean | ("insert" | "update" | "remove" | "soft-remove" | "recover")[];
    /**
     * Indicates if relation column value can be nullable or not.
     */
    nullable?: boolean;
    /**
     * 配置外键的onDelete
     * Database cascade action on delete.
     */
    onDelete?: OnDeleteType;
    /**
     * 配置外键的onUpdate
     * Database cascade action on update.
     */
    onUpdate?: OnUpdateType;
    /**
     * Indicate if foreign key constraints can be deferred.
     */
    deferrable?: DeferrableType;
    /**
     * Indicates whether foreign key constraints will be created for join columns.
     * Can be used only for many-to-one and owner one-to-one relations.
     * Defaults to true.
     * 创建外键,默认是true	
     */
    createForeignKeyConstraints?: boolean;
    /**
     * Set this relation to be lazy. Note: lazy relations are promises. When you call them they return promise
     * which resolve relation result then. If your property's type is Promise then this relation is set to lazy automatically.
     */
    lazy?: boolean;
    /**
     * Set this relation to be eager.
     * Eager relations are always loaded automatically when relation's owner entity is loaded using find* methods.
     * Only using QueryBuilder prevents loading eager relations.
     * Eager flag cannot be set from both sides of relation - you can eager load only one side of the relationship.
     */
    eager?: boolean;
    /**
     * Indicates if persistence is enabled for the relation.
     * By default its enabled, but if you want to avoid any changes in the relation to be reflected in the database you can disable it.
     * If its disabled you can only change a relation from inverse side of a relation or using relation query builder functionality.
     * This is useful for performance optimization since its disabling avoid multiple extra queries during entity save.
     */
    persistence?: boolean;
    /**
     * When a parent is saved (with cascading but) without a child row that still exists in database, this will control what shall happen to them.
     * delete will remove these rows from database.
     * nullify will remove the relation key.
     * disable will keep the relation intact. Removal of related item is only possible through its own repo.
     */
    orphanedRowAction?: "nullify" | "delete" | "soft-delete" | "disable";
}
  • OneToOne(),拥有该列的是从表,拥有关系的一方,即拥有xxxId的一方必须和@JoinColumn()配合使用。第一个参数是一个函数,返回关联的实体类,第二个参数如果有,是指定关系的反方,即关联字段的那方的实体类可以通过它的xxx属性来查询关系,第三个参数是配置关系的选项,包括 cascade级联,createForeignKeyConstraints创建外键,eager查询时总是把关系类也查出来。其他的关系装饰器也大抵如此。

cascade:true只能有一方配置,如果两边都配置cascade:true会报错,如果两边都配置,只要有一边不要配置cascade:[“remove”]就行。如果没有cascade:true关系,那么保存实体时,关联的实体必须先保存到数据库中,否则报错。
报错信息如下
在这里插入图片描述

@Entity()
export class User {
	// 指定关联实体,假如Profile实体通过@OnetoOne() 声明 user:User 字段,那么查询profile时也可以查询到user类
    @OneToOne(type => Profile, profile => profile.user,{
    	createForeignKeyConstraints:false// 不创建外键
	})
    @JoinColumn() // 表示user表有profileId字段关联 profile 表,
    profile: Profile;
}
  • ManyToOne(),拥有该列的表是从表,默认生成关联id,多对一的情况下,可以省略 @JointColumn(), 除非想指定 关联id 和关联列
  • OneToMany(),反向关系,用在一的一方
@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  url: string;
  // 第二个参数指定另一面关系的关联属性,这里可以省略 @JoinColumn(),默认生成字段 userId 
  @ManyToOne(() => User, user => user.photos) 
  user: User;
}

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

  @Column()
  name: string;

  @OneToMany(() => Photo, photo => photo.user) 
  photos: Photo[];
}
  • ManyToMany()
    双方都必须使用,而且必须有一方使用@JoinTable()
@Entity()
export class Post {
    @ManyToOne(type => Category)
    @JoinColumn({
        name: "cat_id",// 指定列名
        referencedColumnName: "name" // 引用的Category的列名
    })
    category: Category;
}
  • JoinColumn()
    指定关系列字段,用于一对一,多对一和多对多,可以设置 cascade,createForeignKeyConstraints,以及另一面的关系属性。
  • JoinTable()
    用于多对多添加中间表,并指定拥有关系的列,只需要一方添加即可。一般要配合@ManyToMany()使用,还可以配置关联表名称和指定关联的列名和关联表的列名
  • RelationId()
    可以获取关联的实体的id,包括多对一和多对多,此 id 仅用于展示,对其修改并不会增删改关系
@Entity()
export class Post {
    @ManyToOne(type => Category)
    category: Category;

    @RelationId((post: Post) => post.category) // 需要指定目标关系
    categoryId: number;
}

@Entity()
export class Post {
    @ManyToMany(type => Category)
    categories: Category[];

    @RelationId((post: Post) => post.categories)
    categoryIds: number[];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/440322.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《TCP/IP详解 卷一》第13章 TCP连接管理

目录 13.1 引言 13.2 TCP连接的建立与终止 13.2.1 TCP半关闭 13.2.2 同时打开与关闭 13.2.3 初始序列号 13.2.4 例子 13.2.5 连接建立超时 13.2.6 连接与转换器 13.3 TCP 选项 13.3.1 最大段大小选项 13.3.2 选择确认选项 13.3.3 窗口缩放选项 13.3.4 时间戳选项与…

开启AI绘画新纪元:让创意在指尖绽放

文章目录 一、了解AI绘画的基本原理二、选择合适的AI绘画工具三、掌握AI绘画的基本技巧四、借鉴与创新:从模仿到创作五、参与社区交流,共同成长《AI绘画教程:Midjourney使用方法与技巧从入门到精通》亮点推荐内容简介作者简介目录 在科技日新…

OpenAI (ChatGPT)中国免费试用地址

GitHub - click33/chatgpt---mirror-station-summary: 汇总所有 chatgpt 镜像站,免费、付费、多模态、国内外大模型汇总等等 持续更新中…… 个人能力有限,搜集到的不多,求大家多多贡献啊!众人拾柴火焰高!汇总所有 cha…

基于java+springboot+vue实现的宠物健康咨询系统(文末源码+Lw)23-206

摘 要 本宠物健康咨询系统分为管理员还有用户两个权限,管理员可以管理用户的基本信息内容,可以管理公告信息以及宠物健康知识信息,能够与用户进行相互交流等操作,用户可以查看宠物健康知识信息,可以查看公告以及查看…

目标检测——摩托车头盔检测数据集

一、简介 首先,摩托车作为一种交通工具,具有高速、开放和稳定性差的特点,其事故发生率高,伤亡率排在机动车辆损伤的首位。因此,摩托车乘员头盔对于保护驾乘人员头部安全至关重要。在驾乘突发状况、人体受冲击时&#…

【微信小程序】传参存储

目录 一、本地数据存储 wx.setStorage wx.setStorageSync 1.1、异步缓存 存取数据 1.2、同步缓存 存取数据 二、使用url跳转路径携带参数 2.1、 wx.redirectTo({}) 2.2、 wx.navigateTo({}) 2.3、 wx.switchTab({}) 2.4 、wx.reLaunch({}) 2.5、组件跳转 三、…

自动化测试框架robotframework安装教程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1.下载安装robotframework2.安装wxpython3.在线安装robotframework-ride4.安装selenium2library5.安装databaselibrary7.安装PyMySql8.下载浏览器驱动程序*9.启动ro…

C++:Stack和Queue的模拟实现

创作不易,感谢三连! 一、容器适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。 就如同是电源适配器将不适用的交流电…

阿里云服务器怎么使用?3分钟搭建网站教程2024新版

使用阿里云服务器快速搭建网站教程,先为云服务器安装宝塔面板,然后在宝塔面板上新建站点,阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例,来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

代码随想录第53天|● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划

文章目录 ● 1143.最长公共子序列思路:代码一:dp二维数组代码二:滚动数组 ● 1035.不相交的线思路:代码:(滚动数组) ● 53. 最大子序和 动态规划思路代码:代码二:单一元素…

许多人可能还不了解这个信息差:美赛的第一批 EI 已经录用,不用再犹豫啦

格局打开,美赛论文转学术论文发表 🚀🚀 各位同学,美赛已经结束了一段时间,你们是否还在焦急地等待最终成绩的公布?一些有远见的同学已经提前收到了一份喜讯:他们的美赛论文已被转化为学术论文并…

2024年博管办香江学者、澳门青年学者、中德博士后 交流项目申报工作启动

近日,中国博士后科学基金会官网发布了2024年博士后国(境)外学术交流项目申报指南,以下知识人网小编仅转载香江学者计划、澳门青年学者计划、中德博士后交流项申报指南并做重点解读。 知识人网整理 各省、自治区、直辖市及新疆生产…

Sora的双重边缘:视频生成的革新与就业的再思考

随着科技的日新月异,人工智能(AI)和机器学习(ML)技术如潮水般涌入我们的日常生活,为各个领域带来了翻天覆地的变化。在这一浪潮中,Sora作为一款前沿的AI视频生成工具,凭借其高度逼真…

vue 使用 PrintJs 实现打印pdf效果

一、print.js介绍 Print.js主要是为了帮助我们直接在应用程序中打印PDF文件,而无需离开界面,并且不使用嵌入。对于用户不需要打开或下载PDF文件的特殊情况,他们只需要打印它们。 例如,当用户请求打印在服务器端生成的报告时&…

便携式测速仪的工作原理

TH-LS5】便携式测速仪的工作原理主要基于多普勒效应。当测速仪发射电磁波并碰触到物体时,电磁波会被反射回来。如果触碰到的物体有朝向或背向的位移运动,那么测速仪发射与反射回来的电磁波之间会存在一个频率差。这个频率差会被测速仪捕获,并…

上海雷卯可以解决YPbPr/ YCbCr接口 ESD/EOS静电浪涌问题

YPbPr /YCbCr 接口传输的是视频信号,不传输音频信号。YPbPr 和 YCbCr 都是视频信号的颜色编码格式,多应用于机顶盒(Set-top box),TV电视,投影仪,游戏机和DVD播放器。 YPbPr:是一种模拟视频接口…

2.DOM-事件基础(注册事件、tab栏切换)(案例:注册、轮播图)

案例 注册事件 <!-- //disabled默认情况用户不能点击 --><input type"button" value"我已阅读用户协议(5)" disabled><script>// 分析&#xff1a;// 1.修改标签中的文字内容// 2.定时器// 3.修改标签的disabled属性// 4.清除定时器// …

前端实现扫同一个二维码,可以跳转到微信小程序和支付宝小程序?

前端如何实现扫同一个二维码&#xff0c;可以跳转到微信小程序和支付宝小程序&#xff1f; 不知道大家有没有遇到过这样的需求&#xff1a;扫描同一个二维码&#xff0c;要如何区分是微信还是支付宝扫码。然后进入微信和支付宝的小程序&#xff1f;&#xff1f; 就我目前所知道…

部署 LVS(nginx)+keepalived高可用负载均衡集群

目录 一、集群的概述 1、什么是集群 2、普通集群与负载均衡集群 2.1 普通集群&#xff08;Regular Cluster&#xff09; 2.2 负载均衡集群&#xff08;Load Balancing Cluster&#xff09; 2.3 高可用集群&#xff08;High Availability Cluster&#xff09; 2.4 区别 …

网站开发之旅:从概念到实现

在我成为一名专业的网站开发者的过程中&#xff0c;我有幸参与了多个激动人心的项目。其中&#xff0c;一个我印象尤为深刻的经历是&#xff0c;开发一个名为“文案推荐网”的主题网站&#xff08;www.zimeiti.love&#xff09;。这个项目不仅让我深入了解了网站开发的各个方面…