Vona ORM如何实现支持多数据库和多数据源配置?

摘要:在Vona ORM中实现多数据库多数据源非常直观、简便。下面以 Model UserOrder 为例,通过查询用户的订单列表,来演示多数据库多数据源的使用方法
在Vona ORM中实现多数据库/多数据源非常直观、简便。下面以 Model User/Order 为例,通过查询用户的订单列表,来演示多数据库/多数据源的使用方法 准备Models 先准备两个 Models:User/Order Model Order @Model({ entity: EntityOrder, }) class ModelOrder{} 需要指定ModelOrder关联的Entity,限于篇幅,EntityOrder代码从略 Model User @Model({ entity: EntityUser, relations: { orders: $relation.hasMany(() => ModelOrder, 'userId'), }, }) class ModelUser {} 在ModelUser中定义1:n关系: orders 查询数据 然后查询用户的订单列表 class ServiceOrder { async selectUserOrders() { const userId = 1; const userAndOrders = await this.scope.model.user.get( { id: userId, }, { include: { orders: true, }, }, ); } } 到目前为止,使用系统默认数据源查询到了userId=1的用户信息,和该用户的所有订单列表 创建多数据源 接下来,创建两个数据源:user-pg和order-mysql 1. 添加数据源的类型定义 在 VSCode 中,通过右键菜单Vona Init/Types在模块中创建类型文件 然后在类型文件中添加类型定义 {module path}/src/types/index.ts declare module 'vona-module-a-orm' { export interface IDatabaseClientRecord { 'user-pg': never; 'order-mysql': never; } } IDatabaseClientRecord是模块vona-module-a-orm提供的接口类型。在这里通过接口合并的机制来添加新的数据源类型 2. 数据源配置 在项目的App config文件中定义数据源的配置信息。由于前面已经添加了数据源类型,在App config文件中就可以享受完整的类型提示 src/backend/config/config/config.ts // database config.database = { clients: { 'user-pg': { client: 'pg', connection: { host: '127.0.0.1', port: 5432, user: 'postgres', password: '', database: 'user-xxx', }, }, 'order-mysql': { client: 'mysql2', connection: { host: '127.0.0.1', port: 3306, user: 'root', password: '', database: 'order-xxx', }, }, }, }; user-pg: 使用数据库方言:pg order-mysql: 使用数据库方言:mysql2 使用数据源:动态方式 可以在代码中动态使用数据源: class ServiceOrder { async selectUserOrders() { const userId = 1; + const modelUser = this.scope.model.user.newInstance('user-pg'); const userAndOrders = await modelUser.get( { id: userId, }, { include: { orders: true, }, }, ); } } newInstance: 传入要使用的数据源,返回新的 Model 实例 到目前为止,使用数据源user-pg查询用户信息,使用系统默认数据源查询订单列表 使用数据源:Relation动态选项 可以在 relation 选项中动态指定数据源: class ServiceOrder { async selectUserOrders() { const userId = 1; const modelUser = this.scope.model.user.newInstance('user-pg'); const userAndOrders = await modelUser.get( { id: userId, }, { include: { orders: { + meta: { + client: 'order-mysql', + }, }, }, }, ); } } meta.client: 指定 relation orders要使用的数据源 到目前为止,使用数据源user-pg查询用户信息,使用数据源order-mysql查询订单列表 使用数据源:Model配置 也可以直接在 Model 中配置数据源,从而简化查询代码 Model Order @Model({ entity: EntityOrder, + client: 'order-mysql', }) class ModelOrder{} 在VonaJS框架中,可以非常方便的为@Model装饰器指定参数 Model User @Model({ entity: EntityUser, + client: 'user-pg', relations: { orders: $relation.hasMany(() => ModelOrder, 'userId'), }, }) class ModelUser {} 查询数据 现在,又可以使用常规的方式查询用户的订单列表 class ServiceOrder { async selectUserOrders() { const userId = 1; const userAndOrders = await this.scope.model.user.get( { id: userId, }, { include: { orders: true, }, }, ); } } 使用数据源:App Config配置 也可以在 App config 中配置 Model options: src/backend/config/config/config.ts // onions config.onions = { model: { 'test-vona:user': { client: 'user-pg', }, 'test-vona:order': { client: 'order-mysql', }, }, }; 在VonaJS框架中,可以在App Config文件中提供配置,用于覆盖对应Model的options配置 于是,也可以使用常规的方式查询用户的订单列表 使用数据源:Relation静态选项 也可以在定义 Relation 时指定静态选项: @Model({ entity: EntityUser, client: 'user-pg', relations: { orders: $relation.hasMany(() => ModelOrder, 'userId', { + meta: { + client: 'order-mysql', + }, }), }, }) class ModelUser {} 同样,也可以使用常规的方式查询用户的订单列表 Vona ORM已开源:github.com/vonajs/vona