multiple-data-sources
在一个数据源中使用多个数据库
要在单个数据源中使用多个数据库,可以为每个实体指定数据库名称:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity({ database: "secondDB" })
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
firstName: string
@Column()
lastName: string
}
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity({ database: "thirdDB" })
export class Photo {
@PrimaryGeneratedColumn()
id: number
@Column()
url: string
}
User
实体将被创建在 secondDB
数据库中,Photo
实体将被创建在 thirdDB
数据库中。
所有其他实体将被创建在数据源选项中定义的默认数据库中。
如果您想从不同的数据库中选择数据,只需提供实体:
const users = await dataSource
.createQueryBuilder()
.select()
.from(User, "user")
.addFrom(Photo, "photo")
.andWhere("photo.userId = user.id")
.getMany() // userId is not a foreign key since its cross-database request
此代码将生成以下 SQL 查询(根据数据库类型):
SELECT * FROM "secondDB"."user" "user", "thirdDB"."photo" "photo"
WHERE "photo"."userId" = "user"."id"
您还可以指定表路径而不是实体:
const users = await dataSource
.createQueryBuilder()
.select()
.from("secondDB.user", "user")
.addFrom("thirdDB.photo", "photo")
.andWhere("photo.userId = user.id")
.getMany() // userId is not a foreign key since its cross-database request
此功能仅支持 MySQL 和 MSSQL 数据库。
在单个数据源中使用多个模式
要在应用程序中使用多个模式,只需在每个实体上设置 schema
:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity({ schema: "secondSchema" })
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
firstName: string
@Column()
lastName: string
}
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity({ schema: "thirdSchema" })
export class Photo {
@PrimaryGeneratedColumn()
id: number
@Column()
url: string
}
User
实体将被创建在 secondSchema
模式中,Photo
实体将被创建在 thirdSchema
模式中。
所有其他实体将被创建在数据源选项中定义的默认数据库中。
如果您想从不同的模式中选择数据,只需提供实体:
const users = await dataSource
.createQueryBuilder()
.select()
.from(User, "user")
.addFrom(Photo, "photo")
.andWhere("photo.userId = user.id")
.getMany() // userId is not a foreign key since its cross-database request
此代码将生成以下 SQL 查询(根据数据库类型):
SELECT * FROM "secondSchema"."user" "user", "thirdSchema"."photo" "photo"
WHERE "photo"."userId" = "user"."id"
您还可以指定表路径而不是实体:
const users = await dataSource
.createQueryBuilder()
.select()
.from("secondSchema.user", "user") // in mssql you can even specify a database: secondDB.secondSchema.user
.addFrom("thirdSchema.photo", "photo") // in mssql you can even specify a database: thirdDB.thirdSchema.photo
.andWhere("photo.userId = user.id")
.getMany()
此功能仅支持 PostgreSQL 和 MSSQL 数据库。 在 MSSQL 中,您还可以结合使用模式和数据库,例如:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity({ database: "secondDB", schema: "public" })
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
firstName: string
@Column()
lastName: string
}
复制
您可以使用 TypeORM 设置读/写复制。以下是一个复制选项的示例:
{
type: "mysql",
logging: true,
replication: {
master: {
host: "server1",
port: 3306,
username: "test",
password: "test",
database: "test"
},
slaves: [{
host: "server2",
port: 3306,
username: "test",
password: "test",
database: "test"
}, {
host: "server3",
port: 3306,
username: "test",
password: "test",
database: "test"
}]
}
}
所有模式更新和写操作都使用 master
服务器执行。
由 find 方法或 select 查询构建器执行的所有简单查询都使用随机的 slave
实例。
由 query 方法执行的所有查询都使用 master
实例。
如果您希望在查询构建器创建的 SELECT 语句中明确使用 master,请使用以下代码:
const masterQueryRunner = dataSource.createQueryRunner("master")
try {
const postsFromMaster = await dataSource
.createQueryBuilder(Post, "post")
.setQueryRunner(masterQueryRunner)
.getMany()
} finally {
await masterQueryRunner.release()
}
如果您想在原始查询中使用 slave
,您还需要明确指定查询运行器。
const slaveQueryRunner = dataSource.createQueryRunner("slave")
try {
const userFromSlave = await slaveQueryRunner.query(
"SELECT * FROM users WHERE id = $1",
[userId],
slaveQueryRunner,
)
} finally {
return slaveQueryRunner.release()
}
请注意,由 QueryRunner
创建的连接需要明确释放。
复制支持 mysql、postgres 和 sql server 数据库。
Mysql 支持深度配置:
{
replication: {
master: {
host: "server1",
port: 3306,
username: "test",
password: "test",
database: "test"
},
slaves: [{
host: "server2",
port: 3306,
username: "test",
password: "test",
database: "test"
}, {
host: "server3",
port: 3306,
username: "test",
password: "test",
database: "test"
}],
/**
* If true, PoolCluster will attempt to reconnect when connection fails. (Default: true)
*/
canRetry: true,
/**
* If connection fails, node's errorCount increases.
* When errorCount is greater than removeNodeErrorCount, remove a node in the PoolCluster. (Default: 5)
*/
removeNodeErrorCount: 5,
/**
* If connection fails, specifies the number of milliseconds before another connection attempt will be made.
* If set to 0, then node will be removed instead and never re-used. (Default: 0)
*/
restoreNodeTimeout: 0,
/**
* Determines how slaves are selected:
* RR: Select one alternately (Round-Robin).
* RANDOM: Select the node by random function.
* ORDER: Select the first node available unconditionally.
*/
selector: "RR"
}
}