typeorm是一个ORM框架,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了。
数据库连接
1.使用createConnection或者createConnections进行数据库连接
import "reflect-metadata";
import { createConnection } from "typeorm";
import { Photo } from "./entity/Photo";
createConnection({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "admin",
database: "test",
entities: [Photo],
synchronize: true,
logging: false
})
.then(connection => {
// 这里可以写实体操作相关的代码
})
.catch(error => console.log(error));
- entities属性是配置需要在数据库中映射出表的实体类。也可以使用通配符进行实体的配置:
entities: [__dirname + "/entity/*.js"], - 设置
synchronize可确保每次运行应用程序时实体都将与数据库同步。 - 使用
createConnections可以创建多个数据库连接
2,使用配置ormconfig.json文件的方式进行数据库连接,
当使用配置文件的时候,createConnection或者createConnections调用传入为空的时候,会自动查找配置文件的内容,然后根据此配置进行数据库的连接。
{\
"type": "mysql",\
"host": "localhost",\
"port": 3306,\
"username": "test",\
"password": "test",\
"database": "test"\
}
typeorm也支持其他ormconfig.[format]格式的文件的配置文件。支持的 ormconfig 文件格式有:.json, .js, .env, .yml 和 .xml。
3,使用ConnectionManager进行数据库连接
import { getConnectionManager, ConnectionManager, Connection } from "typeorm";
const connectionManager = getConnectionManager();
const connection = connectionManager.create({
type: "mysql",
host: "localhost",
port: 3306,
username: "test",
password: "test",
database: "test"
});
await connection.connect(); // 执行连接
如果你想创建连接并获取实例可以使用此种方式。但是这种方式将不能使用getConnection获取连接。
获取数据库连接:
import { getConnection } from "typeorm";
const secondConnection = getConnection("test2-connection");
可以在一个连接中使用多个数据库,只需要在对应的实体类中加上对应的数据库即可:
@Entity({ database: "secondDB" })
export class User {}
实体-数据库表的映射
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column("double")
age: number;
}
- @Entity注解能够实现实体表到数据库表的映射,
- @Column是对应列的映射,可以设置对应列的类型。
创建不同关系的数据库表
1.一对一关系
@Entity()
export class PhotoMetadata {
...
@OneToOne(type => Photo)
@JoinColumn()
photo: Photo;
}
- @OneToOne表示与哪个实体对应的数据库表进行关联关系
- @JoinColumn()表示对应关系的所有者 此实体对应的数据库表photo-metadata中会有自动建立一个外键:
photoId | int(11) | FOREIGN KEY
现在PhotoMetadata和Photo之间建立的只是单向关系,Photos对PhotoMetadata的信息却一无所知,为了解决这个问题需要建立双向关系:
@Entity()
export class PhotoMetadata {
@OneToOne(type => Photo, photo => photo.metadata)
@JoinColumn()
photo: Photo;
}
@Entity()
export class Photo {
@OneToOne(type => PhotoMetadata, photoMetadata => photoMetadata.photo)
metadata: PhotoMetadata;
}
取出关系对象的数据:
let photoRepository = connection.getRepository(Photo);
let photos = await photoRepository.find({ relations: ["metadata"] });
可以看出通过photoRepository可以拿到phone实体关联的PhotoMetadata数据
2.一对多关系
@Entity()
export class Author {
@OneToMany(type => Photo, photo => photo.author)
photos: Photo[];
}
@Entity()
export class Photo {
@ManyToOne(type => Author, author => author.photos)
author: Author;
}
此关系在数据库创建表: Author不会对关系做任何字段的保存,一对多的关系字段总是保存在多的一方,所以会保存在photo表中:
authorId | int(11) | FOREIGN KEY
3.多对多关系
@Entity()
export class Album {
@ManyToMany(type => Photo, photo => photo.albums)
@JoinTable()
photos: Photo[];
}
export class Photo {
@ManyToMany(type => Album, album => album.photos)
albums: Album[];
}
@JoinTable指定关系所有者
运行后,ORM 将创建album_photos_photo_albums_联结表:
album_id | int(11) | PRIMARY KEY FOREIGN KEY
photo_id | int(11) | PRIMARY KEY FOREIGN KEY
操作数据库的三种方式
1.Entity Manager
createConnection(/*...*/)
.then(async connection => {
/*...*/
let savedPhotos = await connection.manager.find(Photo);
console.log("All photos from the db: ", savedPhotos);
})
.catch(error => console.log(error));
2.Repositories
createConnection(/*...*/)
.then(async connection => {
...省略部分代码
let photoRepository = connection.getRepository(Photo);
await photoRepository.save(photo);
})
3.QueryBuilder(构建几乎任何复杂性的 SQL 查询)
createConnection(/*...*/)
.then(async connection => {
let photos = await connection
.getRepository(Photo)
.createQueryBuilder("photo")
.innerJoinAndSelect("photo.metadata", "metadata")
.getMany();
})
.catch(error => console.log(error));