typeorm学习笔记

概述

  • TypeORM是一个对象关系映射框架,它可以运行在 NodeJS、Browser、Cordova、PhoneGap、Ionic、React Native、Expo 和 Electron 平台上,
  • 可以与 TypeScript 和 JavaScript (ES5,ES6,ES7,ES8)一起使用。
  • 它的目标是始终支持最新的 JavaScript 特性并提供额外的特性以帮助你开发任何使用数据库的(不管是只有几张表的小型应用还是拥有多数据库的大型企业应用)应用程序。
  • 还兼容各种主流数据库

官网

安装

npm install typeorm -g

tips: 如果出现安装失败,那么就是没有权限的问题。mac就在代码前输入sudo提升权限,windows就使用右键管理员身份运行再复制以上的代码。

生成项目

typeorm init --name MyProject --database mysql
  • -name 跟着的是创建项目的项目名
  • database 跟着的是要使用的数据库:mysql oracle SQL Server等

配置文件

{
   "type": "mysql",    //数据库类型
   "host": "localhost",//数据库地址
   "port": 3306,       //端口号
   "username": "test", //用户名
   "password": "test", //密码
   "database": "test", //使用哪一个数据库
   "synchronize": true,//是否同步,true就是将src/entity里面定义的数据模块同步到数据库生成数据表
   "logging": false,   //是否打印日志,执行sql语句时候输出原生sql,也可以配置成一个数组["query", "error", "schema"]指定sql的执行类型
   "entities": [
      "src/entity/**/*.ts"    //实体类的路径
   ],
   "migrations": [
      "src/migration/**/*.ts" //数据库迁移文件生成路径
   ],
   "subscribers": [
      "src/subscriber/**/*.ts" 
   ],
   "cli": {
      "entitiesDir": "src/entity",
      "migrationsDir": "src/migration",
      "subscribersDir": "src/subscriber"
   }
}

实体类

以自动生成的User.ts为例

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

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({
	    type: 'varchar',//字段类型
	    nullable: false,//是否为空
	    length: 50,//长度
	    unique: true,//是否唯一
	    name: 'firstName', // 映射到表的字段名,如果是一样的可以不指定
	    comment: '字'
  	})
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    age: number;

  • Entity() 就相当于映射到数据库中的表,class 的名字就对应表的名字
  • PrimaryGeneratedColumn() 相对应表的主键,而且是自动递增的。
  • PrimaryColumn() 这个就是主键不自动递增
  • Column() 表示表中的列
  • type配置字段类型,在mysql中字符类型可能是char、varchar、text,数字类型可能是int、tinyint,小数类型可能是float、double、decimal(10,2)等。
    name: 真正映射到mysql数据库中字段名字,如果不指定会默认以对象的字段为名字(建议都指定)
    length: 长度,比如在mysql中字段为varchar的时候指定字段长度
    nullable: 在mysql中字段是否可以为NULL值,默认为false
    select: 改字段是否可以被查询出来(针对使用typeORM的查寻操作,不针对你使用原生SQL语句操作),默认为true表示可以被查询出来
    default: 默认值,比如插入数据的时候,没传递该字段的值,就默认一个值
    unique: 是否唯一约束
    comment: 备注该字段是做什么的(建议都写上,方便阅读)
    enum: 枚举类型
    array: 该列是否以数组
  • 更多的注解

增删改查

  • 查询
createConnection().then(async connection => {
	console.log("Inserting a new user into the database...");
	const user = new User();
	user.firstName = "Timber";
	user.lastName = "Saw";
	user.age = 24;
	const users = await connection.manager.find(User);
    console.log("Loaded users: ", users);
}).catch(error => console.log(error));

除了find()之外还有一下几种方法
在这里插入图片描述

  • 修改
createConnection().then(async connection => {
	onst userRepository = connection.getRepository(User);
    // 根据句柄去查询实体findOne传递数字会默认根据id查询
    const user2 = await userRepository.findOne(1);
    console.log(user2);
    user2.firstName = "wdb";
    await userRepository.save(user2);
}).catch(error => console.log(error));

结果:
在这里插入图片描述

  • 删除
createConnection().then(async connection => {
	onst userRepository = connection.getRepository(User);
    const user2 = await userRepository.findOne(4);
    await userRepository.remove(user2);
}).catch(error => console.log(error));

结果:
在这里插入图片描述

  • 添加

第一种方式:通过save将对象添加进数据库

createConnection().then(async connection => {
	const user = new User();
    user.firstName = "Timber";
    user.lastName = "Saw";
    user.age = 24;
    await connection.manager.save(user);
}).catch(error => console.log(error));

第二种方式:使用Repository句柄将对象添加进数据库

createConnection().then(async connection => {
	const user = new User();
    user.firstName = "Timber";
    user.lastName = "Saw";
    user.age = 28;
    const userRepository = connection.getRepository(User);
    userRepository.insert(user);
}).catch(error => console.log(error));

结果:
在这里插入图片描述

一对一

  • 首先我们先创建UserExtend表,它是user表的详情表
import {
	Entity,
	PrimaryGeneratedColumn,
	Column,
	OneToOne,
	JoinColumn,
} from "typeorm";
import { User } from "./User";

@Entity({ name: "user_extend" })
export class UserExtend {
	@PrimaryGeneratedColumn()
	id: number;

	@Column({
		type: "varchar",
		length: 11,
		nullable: true,
		name: "mobile",
		comment: "手机号码",
	})
	mobile: string;

	@Column()
	address: string;

	// 使用@OneToOne装饰允许我们在两个实体之间创建一对一的关系
	@OneToOne((type) => User, (user) => user.userDetail)
	// @JoinColumn装饰器,表明实体键的对应关系
	@JoinColumn()
	user: User;
}
  • 然后在user表中添加新的字段
import {Entity, PrimaryGeneratedColumn, Column,OneToOne,
	JoinColumn} from "typeorm";
import { UserExtend } from "./UserExtend";
@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    age: number;

    @OneToOne((type) => UserExtend, (userExtend) => userExtend.user)
	@JoinColumn()
	userDetail: UserExtend;
}

  • 在index.ts中关联两个表的字段
import "reflect-metadata";
import {createConnection} from "typeorm";
import {User} from "./entity/User";
import {UserExtend} from "./entity/UserExtend";
createConnection().then(async connection => {
    const user = new User();
    user.firstName = "dwadawd";
    user.lastName = "Sadasw";
    user.age = 28;
    
    const userExtend = new UserExtend();
    userExtend.mobile = '13959058402';
    userExtend.address = '福建省xxxxxxx';
    //给两个数据模型关联起来
    userExtend.user = user;
    
    const userRepository = connection.getRepository(User);
    //先插入user获取user的id
    await userRepository.save(user);
	
    const userExtendRepository = connection.getRepository(UserExtend);
    await userExtendRepository.save(userExtend);
    console.log('插入数据成功');
}).catch(error => console.log(error));

结果:
在这里插入图片描述

  • 查询
    查询用户详情表的user有字段的数据
createConnection().then(async connection => {
    const userExtendRepository = connection.getRepository(UserExtend);
    const result = await userExtendRepository.find({ relations: ["user"] });
    console.log(result);
}).catch(error => console.log(error));

在这里插入图片描述
查询用户表的userDetail有字段的数据

createConnection().then(async connection => {
    const userRepository = connection.getRepository(User);
    // await userRepository.save(user);
    const res = await userRepository.find({relations:["userDetail"]});
    console.log(res);
}).catch(error => console.log(error));

在这里插入图片描述

  • 一对多

我们先添加一个Article表,在表中关联userid

import {
	Entity,
	PrimaryGeneratedColumn,
	Column,
	CreateDateColumn,
	UpdateDateColumn,
    ManyToOne,
} from "typeorm";
import {User} from "./User"

@Entity()
export class Article {
    @PrimaryGeneratedColumn({
        type:"int",
        name:"id",
        comment:"id"
    })
    id:number;

    @Column({
        type:"varchar",
        nullable:false,
        length:255,
        name:"title",
        comment:"标题"
    })
    title:string;

    @Column({
        type:"varchar",
        nullable:false,
        length:255,
        name:"summary",
        comment:"摘要"
    })
    summary:string;

    @Column({
        type:"varchar",
        nullable:false,
        length:255,
        name:"picture",
        comment:"图片"
    })
    picture:string;

    @Column({
        type:"text",
        nullable:true,
        name:"content",
        comment:"内容"
    })
    content:string;

    @CreateDateColumn({
        type:"timestamp",
        nullable:false,
        name:"create_time",
        comment:"创建时间"
    })
    createTime:Date;

    @UpdateDateColumn({
        type:"timestamp",
        nullable:false,
        name:"update_time",
        comment:"更新时间"
    })
    updateTime:Date;

    @ManyToOne((type) => User, (user) => user.article)
    user:User;
} 

在User表中我们需要添加一个字段

	@OneToMany((type)=> Article,article=>article.user)
    article:Article[]

向表中添加数据后我们就可以查询了

createConnection().then(async connection => {
    const userRepository = connection.getRepository(User);
	const result = await userRepository.find({ relations: ["article"] });
    console.log(result);
}).catch(error => console.log(error));	
	

或者反向查询

createConnection().then(async connection => {
    const articleRepository = connection.getRepository(Article);
	const result = await articleRepository.find({ relations: ["user"] });
    console.log(result);
}).catch(error => console.log(error));	
	

结果:
在这里插入图片描述
在这里插入图片描述

  • 多对多
    一篇文章通常不只一个标签,而一个标签不只对应一篇文章这就是多对多的关系,一般多对多的关系都会用中间表来关联,所以我们需要创建一个中间表。

Tag.ts

import { Column,Entity, ManyToMany, PrimaryGeneratedColumn } from "typeorm";
import { Article } from "./Article";
@Entity()
export class Tag {

    @PrimaryGeneratedColumn({
        type:'int',
        name:'id',
        comment:'主键id'
    })
    id:number;

    @Column({
        type:'varchar',
        length:50,
        name:'tagName',
        comment:'标签名'
    })
    tagName:string;

    @ManyToMany((type) => Article, (article) => article.tag)
    @JoinTable({name: 'article_tag'})
    article:Article[];
    
}

Article.ts
增加多对多的字段

	@ManyToMany((type) => Tag, (tag) => tag.article)
	tag: Tag[];

添加完字段后在控制台中输入npm start数据库的表就会增加tag和article_tag的表
在这里插入图片描述
接下来就可以简单往表里填充数据
在这里插入图片描述

createConnection().then(async connection => {
	const articleRepository = connection.getRepository(Article);
    // relations存放一个数组,可以存放多个关联关系的
    const result = await articleRepository.findOne({where: {id:2},relations: ["tag","user"]});
    console.log(result);
}).catch(error => console.log(error));

运行的效果:
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值