Хранение файлов в базе данных

В этом разделе приводится пример загрузки и сохранения изображений в базу данных приложения, а также описывается, как можно отображать изображения на экранах UI.

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

Во-первых, создайте атрибут типа байтового массива (byte[]) в сущности, например:

@JmixEntity
@Table(name = "PERSON")
@Entity
public class Person {
    // ...

    @Column(name = "PHOTO")
    private byte[] photo;

    public byte[] getPhoto() {
        return photo;
    }

    public void setPhoto(byte[] photo) {
        this.photo = photo;
    }

При запуске приложения Studio генерирует скрипт миграции базы данных для создания соответствующего столбца подходящего базе типа. Например, для PostgreSQL это bytea.

Для загрузки файла из экрана UI используйте компонент FileUploadField, привязанный к атрибуту сущности. Если файл является изображением, можно использовать компонент Image для его отображения на экране. Например:

<data>
    <instance id="personDc"
              class="files.ex1.entity.Person">
        <fetchPlan extends="_base"/>
        <loader/>
    </instance>
</data>
<layout spacing="true">
    <form dataContainer="personDc">
        <column>
            <textField id="nameField" property="name"/>
            <fileUpload id="photoField" property="photo"/> (1)
        </column>
        <column>
            <image dataContainer="personDc" property="photo"
                   height="300" width="300" scaleMode="CONTAIN"/> (2)
            <linkButton id="downloadBtn" caption="Download"/>
        </column>
1 Компонент FileUploadField позволяет пользователям загружать файл и сохранять его в атрибуте сущности.
2 Компонент Image отображает содержимое атрибута сущности.

Для того, чтобы иметь возможность скачивать файл, добавьте кнопку и определите ее обработчик следующим образом:

@Autowired
private InstanceContainer<Person> personDc;

@Autowired
private Downloader downloader; (1)

@Subscribe("downloadBtn")
public void onDownloadBtnClick(Button.ClickEvent event) {
    byte[] photo = personDc.getItem().getPhoto();
    downloader.download(
            photo,
            personDc.getItem().getName() + "-photo", (2)
            DownloadFormat.JPG (3)
    );
}
1 Используйте бин Downloader для скачивания файлов.
2 Определите имя скачанного файла.
3 Если вы знаете формат файла, укажите его в последнем аргументе метода download(). В зависимости от формата веб-браузер будет либо скачивать файл, либо отображать его во вкладке.