Перейти к содержимому

Как сохранить файл pdf в postgresql spring

  • автор:

Как хранить JSON в базе данных, не привлекая внимания DBA

Рано или поздно перед любым разработчиком встает проблема рассогласования импеданса между объектной и реляционной моделью. Звучит дико, конечно. Скажем проще. Рано или поздно каждому разработчику приходится хранить в базе данных что-то такое, что там хранить неудобно. Например, какой-то сущности надо приписывать какие-то дополнительные атрибуты, названия и типы данных. Или кто-то хочет отобразить на реляционные таблицы дерево наследования. Для этих задач есть известные проработанные и неудобные способы решения, которые к тому же легко могут привести к проблемам с производительностью.

Альтернатива этому всему — хранение таких данных в виде JSON. Но реляционные СУБД JSON не любят. Дошло даже до того, что Mongo, киллер-фичей которой как раз является хранение данных в виде JSON, набрала на этом нешуточную популярность. Но, к счастью, эти времена потихоньку отступают. Во многом благодаря усилиям разработчиков PostgreSQL. Раньше все попытки положить JSON в базу данных встречали враждебную реакцию со стороны DBA, аналитиков и QA. Эту реакцию можно описать так: «У нас же тогда будет не база данных, а помойка!»

Спикеры поговорят о связанных с этим проблемах, расскажут, как их можно решить не выходя из реляционной структуры, и продемонстрируют, что с этими решениями не так. Также вы узнаете, в каких случаях для решения этих проблем можно применить JSON и почему львиная доля опасений DBA, аналитиков и QA теперь неактуальна. А еще — как при использовании JSON не выстрелить себе в ногу, потому что нюансы есть.

  • # hibernate
  • # jpa
  • # json
  • # postgresql
  • # spring-data

Как хранить файлы в базе PostgreSQL?

Мне надо хранить в PostgreSQL файлы пользователей но я не как не могу найти информацию об этом в документации. Как мне загружать туда файлы? И как мне организовать доступ к ним? По идее каждый пользователь может иметь файлы, соответсвенно должна быть таблица с путями? Правильно? Как такое вообще традиционно решается в случае с PostgreSQL?

Отслеживать
задан 26 апр 2017 в 21:40
5,327 11 11 золотых знаков 58 58 серебряных знаков 117 117 бронзовых знаков
А зачем файлы хранить именно в БД ?
26 апр 2017 в 21:40

@Mike а как правильно? У меня нет такого условия что именно в БД, это показалось мне логичным. А как обычно делают? Я просто в первый раз с работой с БД сталкиваюсь так что простите за глупые вопросы если что.

26 апр 2017 в 21:42

В бд можно хранить например пути к файлам, а сами файлы просто на диске, так обычно проще. И одного совершенно правильного пути нет. тут уже могут быть нюансы

26 апр 2017 в 21:46
@Mike В бд можно хранить например пути к файлам, а сами файлы просто на диске обычно так делают?
26 апр 2017 в 21:47

ну зависит от того, что потом с ними происходит. Если у вас например web-приложение и файлы надо давать на скачку, то nginx файл пользователю гораздо быстрее и с меньшими накладными расходами отдаст, чем скрипт который будет тащить данные из БД и отдавать пользователю

26 апр 2017 в 21:50

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Вы не можете найти информацию в документации о том, как хранить файлы в базе данных, потому что это неправильно.

Хранить можно, но зачем?

СУБД лишь абстракция над набором файлов (таблиц, индексов и т.д) Вы делаете запрос к таблице, СУБД перемещает указатель в каком-то файле, ставит какие-то блокировки, чтобы выбрать определенную запись, пишет это все в кеш..И теперь становится понятно, что база данных — это лишняя прослойка для доступа к файлам.

Файлы — при использовании по прямому назначению (отдать данные клиенту) всегда быстрее, чем хранение в базе данных, потому что требуется меньше процедур, чтобы их прочитать.

Если вы храните файлы в базе данных, вы забивайте кеш, который должен использоваться для других запросов. Со временем, база данных разрастается, процессы которые отдают файлы забивают свободный пул, возрастает нагрузка и используемое место, вам требуется уже шардинг и другие ненужные процедуры.

Для реализации файлового хранилища, храните адрес сервера (если их несколько) и полный путь к файлу на сервере в таблице и отдавайте файлы через nginx.

P.S Иногда есть логическое обоснование хранения файлов в БД, но к сожалению, это маленький процент общих вариантов.

Разработка распределенной очереди с отложенными задачами на основе PostgreSQL

Максим покажет процесс создания очереди задач на основе реляционной БД. Она поддерживает ретраи и выполнение задач в строгой последовательности по одной сущности. В слайдах будет показан код на Java и SQL: структура таблиц и строчек. Сам метод основан на блокировках Postgres и ожидании блокировки внутри транзакции, пока задача выполняется. Спикер также расскажет про статистику, про то, сколько весит очередь, ее индексы и про то, откуда вообще взяты эти данные (немного обучения диагностике в Postgres). А в конце — еще и результаты нагрузки.

  • # databases
  • # postgresql
  • # queues

Спикеры

Максим Иванов

Компания: Тинькофф

Приглашенные эксперты

Илья Сазонов

Компания: Всегда.Да

Ведущие

Алексей Стукалов

Компания: Haulmont

Другие доклады по теме «Spring and Database»

Смотреть запись
Тип доклада: Доклад

Как хранить JSON в базе данных, не привлекая внимания DBA

Илья Сазонов

Компания: Всегда.Да

Федор Сазонов

Компания: Сбер

  • Доклад на русском языке RU
  • Сложность доклада —

Смотреть запись
Тип доклада: Обсуждение

Блеск и нищета Hibernate

Андрей Беляев

Компания: HAULMONT

Андрей Аркаев

Компания: Naumen

Алексей Стукалов

Компания: Haulmont

Антон Черноусов

Компания: Yandex Cloud

  • Доклад на русском языке RU

Смотреть запись
Тип доклада: Доклад

Spring Boot с Amazon Web Services SDK: взаимодействие основных сервисов

Август Вилакия

Компания: Альфа-Банк

  • Доклад на русском языке RU
  • Сложность доклада —

Смотреть запись
Тип доклада: Доклад

Урок географии для Java-разработчиков. География и Java в одном чайнике

Павел Кислов

Компания: Домклик

  • Доклад на русском языке RU
  • Сложность доклада —

Смотреть запись
Тип доклада: Доклад

Hibernate 6: что нового и почему это важно

Андрей Беляев

Компания: HAULMONT

  • Доклад на русском языке RU
  • Сложность доклада —

Конференция для опытных Java-разработчиков

Мы в социальных сетях

  • Телефон: +7 (812) 313-27-23
  • E-mail: support@jokerconf.com
  • Телеграм: @JUGConfSupport_bot

Загрузка файла из контроллеров Spring

Существует типичная задача, когда нужно сгенерировать PDF-файл на сервере и предоставить его для скачивания пользователю. Например, это может быть отчет, который формируется на основе данных из базы данных, и пользователь должен иметь возможность скачать его в виде PDF-файла.

Идеально для решения этой задачи подходит сочетание двух технологий: шаблонизатора freemarker для формирования HTML-шаблона отчета и библиотеки iText для преобразования HTML в PDF. Однако возникает вопрос — как организовать загрузку этого файла через Spring контроллер?

Генерация PDF

Для начала требуется сгенерировать сам PDF. В качестве шаблона используется HTML, который заполняется данными при помощи freemarker. Затем этот HTML преобразуется в PDF с помощью iText.

String html = freemarkerTemplateEngine.process("reportTemplate", model); ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream(); PdfRendererBuilder builder = new PdfRendererBuilder(); builder.withHtmlContent(html, "/"); builder.toStream(pdfOutputStream); builder.run();

Метод freemarkerTemplateEngine.process заполняет HTML-шаблон данными, а PdfRendererBuilder преобразует HTML в PDF.

Отправка файла через Spring контроллер

Теперь, когда PDF сгенерирован, его можно отправить пользователю. Для этого в контроллере Spring создается новый метод, который возвращает ResponseEntity.

@RequestMapping(value = "/download", method = RequestMethod.GET) public ResponseEntity<byte[]> downloadReport() < byte[] pdfData = generatePdfReport(); // метод, который генерирует PDF HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_PDF); headers.setContentDispositionFormData("filename", "report.pdf"); return new ResponseEntity<>(pdfData, headers, HttpStatus.OK); >

В этом методе генерируется PDF, затем создается новый объект HttpHeaders, в котором устанавливается тип контента и имя файла. Затем создается и возвращается новый объект ResponseEntity, который содержит данные PDF, заголовки и статус HTTP.

Таким образом, при запросе к данному контроллеру пользователь получает PDF-файл, который можно скачать.

Это один из возможных способов решения задачи. Важно помнить, что в разных ситуациях могут потребоваться разные подходы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *