Form и операции с базой данных
Перед началом
Перед тем как продолжить, убедитесь, что у вас есть представление об SQL и связях между таблицами, таких как «один ко многим» и «многие к одному».
Кроме того, необходимы предварительные знания о Forms в Netuno и о том, как они организованы, чтобы извлечь максимум из DB Form.
Введение
При разработке программного обеспечения нам часто нужно получать информацию из базы данных, и использование чистого SQL делает это громоздким и утомительным. DB Form превращает построение SQL-запросов в интуитивный процесс без стресса. С ним вы можете создавать мощные запросы, используя удобные методы, которые абстрагируют сложность необработанного SQL и предлагают подход к разработке запросов, соответствующий вашему ходу мыслей.
Как это работает
В основе DB Form лежит возможность структурировать команды SQL с помощью объектов и методов. Вместо того чтобы писать команды SQL напрямую, DB Form позволяет использовать объектно-ориентированный механизм для программного определения запросов и операций.
Каждый запрос или операция с базой данных представляется как объект.
Вы создаёте экземпляры классов запросов, которые инкапсулируют различные части SQL, такие как выборка, фильтрация, группировка и т. д. А также выполняете операции удаления, вставки и обновления записей.
Инициализация
Всё начинается с инициализации DB Form, которому нужно знать имя базовой или основной формы, которая будет использоваться; иными словами, формы в Netuno всегда представляют таблицы в базе данных, поэтому это равнозначно указанию базовой или основной таблицы.
В этом примере мы инициализируем DB Form из формы/таблицы lyudi:
const dbFormLyudi = _db.form("lyudi")
После инициализации DB Form мы можем выполнять запросы или операции.
Простой запрос
DB Form предоставляет два очень распространённых метода для получения данных, помимо пагинации и DISTINCT-результатов, это:
all— все записи в виде списка.first— получает только первую запись.
См. примеры ниже.
Чтобы получить всех людей:
const dbLyudi = _db.form("lyudi")
.all()
Чтобы получить только одного человека:
const dbChelovek = _db.form("lyudi")
.first()
Фильтры и условия
С помощью where мы можем фильтровать данные, соответствующие определённым условиям.
См. несколько примеров:
const dbChelovek = _db.form("lyudi")
.where(_db.where("lyudi_user_id").equals(_user.id))
.first()
const dbLyudi = _db.form("lyudi")
.where(
_db.where("tip").in(_val.list().add("klient").add("admin"))
.and("pochta").notEqual(null)
).all()
Сравнения Where
_db.where предоставляет объект Where, который поддерживает следующие операции сравнения:
Сравнения с числовыми и текстовыми операторами:
equal(...)илиequals(...)— проверяет равенство, это=.notEqual(...)илиnotEquals(...)— проверяет, отличается ли значение от переданного, это<>.greaterThan(...)— проверяет, больше ли значение переданного, это>.lessThan(...)— проверяет, меньше ли значение переданного, это<.greaterOrEqualsThan(...)— проверяет, больше или равно ли значение переданному, это>=.lessOrEqualsThan(...)— проверяет, меньше или равно ли значение переданному, это<=.
Текстовые условия с оператором LIKE:
startsWith('текст')— если начинается с указанного префикса, этоLIKE '...%'.endsWith('текст')— если заканчивается указанным суффиксом, этоLIKE '%...'.contains('текст')— если содержит термин, этоLIKE '%...%'.
Условия со списками с оператором IN:
in(_val.list()...)— если равно какому-либо значению из списка, это условиеIN (...).notIn(_val.list()...)— если не равно ни одному значению из списка, это условиеNOT IN (...).
Практические примеры запросов
DB Form доступен через ресурс _db.form('form'); после вызова у вас есть базовый запрос, который можно настроить с помощью доступных в нём методов и объектов.
Многие к одному и DISTINCT-результаты
const zapros = _db.form('lyudi')
.where(
_db.where('imya').startsWith('иван')
.and(
_db.where('pochta').contains('иван')
.or('pochta').endsWith('com')
)
)
.link('dolzhnost', _db.where('kod').equal('menedzher'))
.join(
_db.manyToOne(
'netuno_user',
'lyudi_user_id',
_db.where('mail').startsWith('иван')
).join(
_db.manyToOne(
'netuno_group',
'group_id',
_db.where('kod').equal('lyudi')
)
)
)
.get("lyudi.imya", "lyudi_imya")
.get("lyudi.aktivnyi", "lyudi_aktivnyi")
.get("lyudi.uid", "lyudi_uid")
.debug(true)
.distinct(true)
const rezultaty = zapros.all();
В приведённом выше примере мы выполняем запрос к таблице lyudi, связывая её ещё с двумя таблицами, dolzhnost и netuno_user, где dolzhnost связывается через метод link, а netuno_user — через join. Можно заметить, что link гораздо проще, чем join; это потому, что link повторно использует связь из Form Netuno для сопоставления отношения, тогда как join использует только информацию, переданную в метод. Также можно заметить другие использованные методы и объекты, такие как:
where: объект, предоставляемый для построения условий для таблицы.link: метод, который связывает основную таблицу с другой таблицей, используя критерииFormNetuno.join: метод, который принимает объект связи между таблицами.get: метод, определяющий, какие поля будут возвращены в запросе.manyToOne: объект, определяющий тип связи между таблицами, в данном случае связь типаMany To One.debug: метод, определяющий, будет ли построенный запрос выведен в консоль.distinct: метод, определяющий, будет ли к запросу применена командаDISTINCT.all: метод, который выполняет запрос и возвращает результаты в виде списка.
Метод
linkследует использовать только тогда, когда таблицы уже имеют связь черезFormNetuno.
Первая запись со связью и сортировкой
const zapros = _db.form('lyudi')
.where(
_db.where('imya').startsWith('иван')
.and('pochta').in(
_val.list().add('first@mail.com').add('second@mail.com'))
)
.link('dolzhnost')
.get("lyudi.imya", "lyudi_imya")
.get("lyudi.aktivnyi", "lyudi_aktivnyi")
.get("dolzhnost.kod", "dolzhnost_kod")
.order('lyudi.vozrast', 'desc')
.debug(true)
const pervyiRezultat = zapros.first();
В конце приведённого выше примера мы вызываем метод first(); он возвращает первое вхождение, найденное при выполнении запроса; если ничего не найдено, он вернёт null.
Пагинация
const zapros = _db.form('lyudi')
.link(
'dolzhnost',
_db.link('zadacha')
)
.get("lyudi.imya", "lyudi_imya")
.get("lyudi.aktivnyi", "lyudi_aktivnyi")
.get("dolzhnost.kod", "dolzhnost_kod")
.group("lyudi.id")
.debug(true)
const stranitsa = zapros.page(_db.pagination(1, 10));
Номер страницы в объекте Pagination начинается с 1, поэтому приведённый выше пример эквивалентен:
offset = 0иlimit = 10.
В конце приведённого выше примера мы вызываем метод page(), передавая в качестве параметра объект pagination, который содержит настройки пагинации. Он вернёт объект страницы с соответствующими атрибутами, например:
{
"hasNext": false,
"hasPrevious": false,
"items": [
{
"dolzhnost_kod": "stazher",
"lyudi_aktivnyi": true,
"lyudi_imya": "Жуниор Фрейтас"
},
{
"dolzhnost_kod": "menedzher",
"lyudi_aktivnyi": true,
"lyudi_imya": "Каио Андраде"
}
],
"pageNumber": 1,
"pageSize": 10,
"totalElements": 2,
"totalPages": 1
}
Вставка записей
Для вставки данных в базу данных используем метод insert, например:
const dbVstavlennyiChelovek = _db.form("lyudi")
.set("imya", "Каио Андраде")
.set("pochta", "kaio@mail.com")
.insert();
С результатом insert мы можем получить id записи, которая была вставлена в базу данных.
Таким образом, в dbVstavlennyiChelovek получаем id вставленной записи следующим образом:
_log.info("ID вставленной записи lyudi: "+ dbVstavlennyiChelovek.getInt('id'))
Редактирование записей
Через объект DB Form вы можете легко и интуитивно обновлять записи запроса.
_db.form('lyudi')
.link(
'dolzhnost',
_db.where('kod').equal('stazher')
)
.set("imya", "новое имя")
.set("pochta", "moyanovyi@mail.com")
.update();
Важно. Методupdate()обновит все вхождения запроса, поэтому будьте внимательны при его использовании.
Кроме того, вы можете использовать другие методы в комбинации, такие как
order()иlimit(), чтобы улучшить ваши запросы.
Удаление записей
DB Form также позволяет просто удалять записи, возвращаемые запросом.
_db.form('lyudi')
.link(
'dolzhnost',
_db.where('kod').equal('stazher')
)
.delete();
Важно. Методdelete()удалит все вхождения запроса, поэтому будьте внимательны при его использовании.
Как и другие, можно комбинировать другие методы, такие как
order()иlimit(), чтобы улучшить результаты.