Реализация репозитория для работы с базами данных
|
|
2 years ago | |
|---|---|---|
| .husky | 2 years ago | |
| src | 2 years ago | |
| .c8rc | 2 years ago | |
| .commitlintrc | 2 years ago | |
| .editorconfig | 2 years ago | |
| .eslintrc.cjs | 2 years ago | |
| .gitignore | 2 years ago | |
| .mocharc.cjs | 2 years ago | |
| .prettierrc | 2 years ago | |
| LICENSE | 2 years ago | |
| README.md | 2 years ago | |
| mocha.setup.js | 2 years ago | |
| package.json | 2 years ago |
Абстракция для работы с базами данных для Node.js
| адаптер | описание |
|---|---|
| memory | хранение данных в памяти процесса Node.js для разработки и тестирования |
| mongodb | MongoDB - система управления NoSQL базами данных (требует установки) |
npm install @e22m4u/repository
Опционально устанавливаем адаптер, например mongodb
npm install @e22m4u/repository-mongodb-adapter
Создаем экземпляр класса Schema
import {Schema} from '@e22m4u/repository';
const schema = new Schema();
Объявляем источник данных myDatasource
schema.defineDatasource({
name: 'myDatasource', // название источника
adapter: 'memory', // выбранный адаптер
});
Объявляем модель заказа order
schema.defineModel({
name: 'order', // название модели
datasource: 'myDatasource', // используемый источник
properties: { // поля модели
cost: 'number', // поле типа "number"
},
relations: { // связи с другими моделями
customer: { // название связи
type: 'belongsTo', // хранить идентификатор цели у себя
model: 'customer', // название целевой модели
foreignKey: 'customerId', // в каком поле хранить идентификатор цели
},
},
});
Объявляем модель покупателя customer
schema.defineModel({
name: 'customer', // название модели
datasource: 'myDatasource', // используемый источник
properties: { // поля модели
name: { // название поля
type: 'string', // тип поля
required: true, // сделать поле обязательным
},
},
relations: { // связи с другими моделями
orders: { // название связи
type: 'hasMany', // искать свой идентификатор в целевой модели
model: 'order', // целевая модель
foreignKey: 'customerId', // в каком поле искать идентификатор
},
},
});
Получаем репозитории для моделей customer и
order
const customerRep = schema.getRepository('customer');
const orderRep = schema.getRepository('order')
Создаем покупателя fedor и его заказы
// создаем покупателя
const fedor = await customerRep.create({name: 'Fedor'});
// и заказы
await orderRep.create({cost: 150, customerId: fedor.id});
await orderRep.create({cost: 250, customerId: fedor.id});
Получаем покупателя методом findById, включая связь с
заказами
const fedorWithOrders = await customerRep.findById(
fedor.id, // искомый идентификатор
{include: ['orders']}, // имена включаемых связей
);
// {
// id: 1,
// name: 'Fedor',
// orders: [
// {id: 1: cost: 150, customerId: 1},
// {id: 2: cost: 250, customerId: 1},
// ],
// }
Получаем заказы и их покупателей методом find
const ordersWithCustomers = await orderRep.find({
// опциональные параметры
where: {customerId: fedor.id}, // фильтрация
order: ['id DESC'], // сортировка результата
limit: 10, // ограничение количества
skip: 0, // пропуск записей
fields: ['cost', 'customerId'], // запрашиваемые поля
include: ['customer'], // включаемые связи
});
console.log(ordersWithCustomers);
// [
// {
// id: 1,
// cost: 150,
// customerId: 1,
// customer: {
// id: 1,
// name: 'Fedor',
// },
// },
// {
// id: 2,
// cost: 250,
// customerId: 1,
// customer: {
// id: 1,
// name: 'Fedor',
// },
// },
// ]
Удаляем данные методами deleteById и
delete
// удаляем покупателя по идентификатору
await customerRep.deleteById(fedor.id); // true
// удаляем заказы по условию
await orderRep.delete({customerId: fedor.id}); // 2
Определяет настройки и способ подключения к базе.
Параметры:
name: string название нового источникаadapter: string выбранный адаптер базы данныхПример:
schema.defineDatasource({
name: 'myDatasource',
adapter: 'memory',
});
Адаптер может иметь параметры, которые передаются при определении источника.
Пример:
schema.defineDatasource({
name: 'myDatasource',
adapter: 'mongodb',
// параметры адаптера:
host: '127.0.0.1',
port: 27017,
});
Описывает набор полей и связей к другим моделям.
Параметры:
name: string название новой моделиdatasource: string выбранный источник данныхproperties: object определения полей моделиrelations: object определения связей моделиПример:
schema.defineModel({
name: 'myModel',
datasource: 'myDatasource',
properties: {...}, // см. ниже
relations: {...}, // см. ниже
});
Описывает набор полей и их настройки.
Типы:
stringnumberbooleanarrayobjectanyПример:
schema.defineModel({
// ...
properties: {
prop1: 'string',
prop2: 'number',
prop3: 'boolean',
prop4: 'array',
prop5: 'object',
prop6: 'any',
},
});
Расширенные параметры:
type: string тип хранимого значенияitemType: string тип элемента массива (для
type: 'array')model: string модель объекта (для
type: 'object')primaryKey: boolean объявить поле первичным ключомcolumnName: string переопределение названия
колонкиcolumnType: string тип колонки (определяется
адаптером)required: boolean объявить поле обязательнымdefault: any значение по умолчанию для
undefinedПример:
schema.defineModel({
// ...
properties: {
prop1: {
type: 'string',
primaryKey: true,
},
prop2: {
type: 'boolean',
required: true,
},
prop3: {
type: 'number',
default: 100,
},
prop3: {
type: 'string',
// фабричное значение
default: () => new Date().toISOString(),
},
prop4: {
type: 'array',
itemType: 'string',
},
prop5: {
type: 'object',
model: 'objectModel',
},
},
});
Описывает набор связей к другим моделям.
Понятия:
Типы:
belongsTo - ссылка на целевую модель находится в
источникеhasOne - ссылка на источник находится в целевой модели
(one-to-one)hasMany - ссылка на источник находится в целевой модели
(one-to-many)referencesMany - массив ссылок на целевую модель
находится в источникеПараметры:
type: string тип связиmodel: string целевая модельforeignKey: string поле для идентификатора целиpolymorphic: boolean|string объявить связь
полиморфной*discriminator: string поле для названия целевой модели
(для polymorphic: true)i. Полиморфный режим belongsTo позволяет динамически
определять цель связи, где имя целевой модели хранится в отдельном поле,
рядом с foreignKey
Связь заказа к покупателю через поле customerId
schema.defineModel({
// ...
relations: {
// ...
customer: {
type: 'belongsTo',
model: 'customer',
foreignKey: 'customerId', // опционально
},
},
});
Полиморфная версия
schema.defineModel({
// ...
relations: {
// ...
customer: {
type: 'belongsTo',
polymorphic: true,
foreignKey: 'customerId', // опционально
discriminator: 'customerType', // опционально
},
},
});
Связь покупателя к заказу, как обратная сторона
belongsTo
schema.defineModel({
// ...
relations: {
// ...
order: {
type: 'hasOne',
model: 'order',
foreignKey: 'customerId', // опционально
},
},
});
Обратная сторона полиморфной версии belongsTo
schema.defineModel({
// ...
relations: {
// ...
order: {
type: 'hasOne',
model: 'order',
polymorphic: 'customer', // имя связи целевой модели
},
},
});
Явное указание foreignKey и
discriminator
schema.defineModel({
// ...
relations: {
// ...
order: {
type: 'hasOne',
model: 'order',
polymorphic: true, // true вместо имени модели
foreignKey: 'customerId', // поле целевой модели
discriminator: 'customerType', // поле целевой модели
},
},
});
Связь покупателя к заказам, как обратная сторона
belongsTo
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'hasMany',
model: 'order',
foreignKey: 'customerId', // опционально
},
},
});
Обратная сторона полиморфной версии belongsTo
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'hasMany',
model: 'order',
polymorphic: 'customer', // имя связи целевой модели
},
},
});
Явное указание foreignKey и
discriminator
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'hasMany',
model: 'order',
polymorphic: true, // true вместо имени модели
foreignKey: 'customerId', // поле целевой модели
discriminator: 'customerType', // поле целевой модели
},
},
});
Связь покупателя к заказам через поле orderIds
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'referencesMany',
model: 'order',
foreignKey: 'orderIds', // опционально
},
},
});
Выполняет операции чтения и записи определенной модели.
Методы:
create(data, filter = undefined)replaceById(id, data, filter = undefined)replaceOrCreate(data, filter = undefined)patchById(id, data, filter = undefined)find(filter = undefined)findOne(filter = undefined)findById(id, filter = undefined)delete(where = undefined)deleteById(id)exists(id)count(where = undefined)Получение репозитория модели:
import {Schema} from '@e22m4u/repository';
const schema = new Schema();
// создаем источник
schema.defineDatasource({name: 'myDatasource', adapter: 'memory'});
// создаем модель
schema.defineModel({name: 'myModel', datasource: 'myDatasource'});
// получаем репозиторий по названию модели
const repositorty = schema.getRepository('myModel');
Переопределение конструктора:
import {Schema} from '@e22m4u/repository';
import {Repository} from '@e22m4u/repository';
import {RepositoryRegistry} from '@e22m4u/repository';
class MyRepository extends Repository {
/*...*/
}
const schema = new Schema();
schema.get(RepositoryRegistry).setRepositoryCtor(MyRepository);
// теперь schema.getRepository(modelName) будет возвращать
// экземпляр класса MyRepository
npm run test
MIT