node.js - nodejs, pg-promise:最佳存储库模式
问题描述
我在为我的 API 选择存储库模式时遇到了一些麻烦。数据库由几个表组成,这些表可以分为两个“部分”。
我是为每个表(第一个示例)做一个存储库还是每个“部分”(第二个示例)只做一个存储库?另一件需要注意的事情是,稍后(在某个月,当 API 的版本 1 生效时),API 将不得不同时管理一个额外的(NoSQL)数据库,而不是代替第一个(示例使用pg-承诺)
第一个例子
first.js : 只管理表'first'
'use strict';
class FirstRepository {
constructor(/*parameters*/) { /* hidden for brevity */ }
makeInsertQuery(params) {
return this.pgp.helpers.insert(params, this.Collections.insert);
// return query like `INSERT INTO first...`
}
// t.* = *Repository (FirstRepository, secondRepository, ...)
insertOne(params) {
return this.Database.tx('MyTag', async t => {
let result = {};
const query = t.first.makeInsertQuery(params) + " RETURNING *";
result.first = await t.one(query);
result.second = await t.second.insertOne(params);
result.third = await t.third.insert(params);
// some other call like that
/**
* LATER = INSERT IN THE OTHER DATABASE
*/
return result;
})
.catch(ex => {
throw ex;
});
}
/* some other function, hidden for brevity */
}
module.exports = FirstRepository
second.js : 只管理表'second'
'use strict';
class SecondsRepository {
constructor(/*parameters*/) { /* hidden for brevity */ }
makeInsertQuery(params) {
return this.pgp.helpers.insert(params, this.Collections.insert);
// return query like `INSERT INTO second...`
}
insertOne(params) {
let second = /* some stuf, hidden for brevity */;
var query = this.makeInsertQuery(second);
return this.Database.one(query)
.then(data => { return data; })
.catch(ex => { throw ex; });
}
/* some other function, hidden for brevity */
}
module.exports = SecondsRepository
第二个例子
// repo1.js
'use strict';
/* FirstPartRepository manage several tables : 'first', 'second' and 'third' */
class FirstPartRepository {
constructor(/*parameters*/) { /* hidden for brevity */ }
makeInsertQuery(params, entity) {
let obj = /* extract it from params */
return this.pgp.helpers.insert(params, this.Collections[entity].insert);
// return query like `INSERT INTO ${entity}...`
}
// In this example, FirstPartRepository manage some table : 'first', 'second' and 'third'
insertOne(params) {
return this.Database.tx('MyTag', async t => {
let result = {};
const insertFirst = t.firstpart.makeInsertQuery(params, 'first') + " RETURNING *",
insertSecond = t.firstpart.makeInsertQuery(params, 'second') + " RETURNING *",
insertThird = t.firstpart.makeInsertQuery(params, 'third') + " RETURNING *";
result.first = await t.one(insertFirst);
result.second = await t.one(insertSecond);
result.third = await t.one(insertThird);
// some other like that
/**
* LATER = INSERT IN THE OTHER DATABASE
*/
return result;
})
.catch(ex => {
throw ex;
});
}
/* some other function, hidden for brevity */
}
module.exports = FirstPartRepository
解决方案
模式Repository
= 对单个实体的一组操作。
在您的情况下,每个存储库都是一个代表单个表上所有操作的类。
在实现复杂的多实体业务逻辑时,您可以通过以下三种方式之一来实现它:
- 您可以让密钥存储库实现高级业务方法
- 您可以创建一个额外的高级存储库以保持高级逻辑分离
- 您可以在存储库模式之外实现它,例如在外部函数中。
选择哪一个 - 取决于应用程序要求及其业务逻辑。
推荐阅读
- mysql - 循环遍历各种表 MySQL
- node.js - Redis 写后置缓存策略
- verilog - 错误 (10170):Test1.sv(29) 附近文本处的 Verilog HDL 语法错误:“程序”;期待描述
- c++ - c++ 前向声明失败 - 在 docker 中运行
- r - 打印几个小标题,总比终端高,不丢失超出部分
- reactjs - NextJS 对 SSG/SSR 和 Google Analytics/cookies 的建议
- android - 如何实例化一个新的 JSONObject Arraylist,它采用函数返回的 Arraylist 的值?
- c++ - 在 CODECHEF C++ 上的 HELP BOB 问题中接受使用向量,但拒绝使用数组
- c++ - 在客户端安装根 CA 证书,使用 OpenSSL 的 C++
- c# - 如何在相同日期的 Richtextbox 中保存单独的约会?