Как правильно передать соединение с базой данных в модель?
Здравствуйте. У меня есть приложение, которое написано с использованием фреймворка Express.
Я не хочу напрямую в маршрутах делать запросы к базе данных. Вместо этого, я хочу создать классы, которые скроют детали реализации (модели). Например, модель пользователя будет иметь следующие функции getById, authorize(login, password), а также некоторые другие.
Вопрос в том, а как передать соединение в эту модель, что бы не открывать соединение при каждом запросе.
Я вижу это так:
const express = require('express);
var users = require('./models/users.js');
const dbDriver = require('db-driver'); / Для данного вопроса какую базу данных я использую не важно
app = express();
dbDriver.connect(host, user, password).then(function(connection) {
users.init(connection); // Передаём объект соединения. Функция init инициализирует внутреннюю переменную, хранящую соединение
app.users = users; // Во всех маршрутах будет видна эта модель через req.local.users
app,listen(3000);
}).catch(e) {
console.log('Unable to start API', e);
});
Поскольку дб не связанна с экспрессом, то самый простой вариант создать базовую модель в которой будет происходить коннект к бд, ссылка на которую будет сохранятся в статическое поле db. Ссылку на дб можно сделать статическим геттером который будет выполнять роль синглтона. Это самое простое. Лучгшее решение заключается в реализации репозитория.
twoone, я думал насчёт синглтона. Понятно, что можно сделать что-то в духе db.init(), а когда нужно соединение, то db.getConnection, который будет всегда возвращать только 1 connection, но я не могу понять, как это передавать внутри приложения.
VadimKholodilo, я же говорю -
1) сделать базовую модель с доступом к дб и от неё наследовать остальные
2) репозиторий
Если вас интересует как передать модели в обработчики (эндпоинты), то это другое дело -
1) использовать механизм экспресса set\get (service locator)
2) отказаться от express в пользу nest с его DI.
Других вариантов нет.
Пример с синглтоном.
class BaseModel {
static getDbConnection(){
// здесь происходит конект к дб
let db = {};
return db;
}
static db = null;
// геттер выступающий в роли синглтон
get db() {
if(!BaseModel.db){
BaseModel.db = BaseModel.getDbConnection();
}
return BaseModel.db;
}
}
class UserModel extends BaseModel {
getName(){
return this.db // обращаемся к дб суперкласса
}
}
let userModel = new UserModel();
twoone, от Express уже не отказаться. Много чего написано уже. Вариант с базовой моделью мне нравится. Просто, до сих пор, почему-то немного непривычно использовать классы в JavaScript
Все очень просто. Чувак захотел выучить js. Записался на курсы на которых стал преуспевать. Препод отметил его способности и сказал что ему самому нужно быть преподователем. У чувака это вызвало улыбку и после непродолжительно обмена любезностями он понял что это всерьез. И боьшинство соглашается. То есть ведутся! Дело в том что подобные курсы устроены по принципу пирамиды. Начинаешь учить, отбираешь способных, даешь им свои сертификаты, собираешь с них проценты, сам отстроняешься от работы и живешь на проценты.
Так вот это я к чему. Ити преподователи-новички хаят классы только потому что они им сложны в понимании, а те приложухи которые они пишут не наделены сложностью. Дело в том, что пока ты пишишь чисто на фраймворках, тио вполне хватает объектов и функций. Но как только ты начинаешь писать сами фраймворки, то все сводится на нет, поскольку вложенность функций и пересечение контекстов просто выносят мозг.
Класс это всего-лишь инкапсуляция, ничего большего. Боятся классов значить орать во все горло что ты недопрофессионал. И стаж утверждающих обратно ничего не говорит, поскольку можно и двадцать лет на jQ писать. И как правило именно такие чуваки и пытаются стажем рот заткнуть поскольку других аргументов просто нет.