文件保存至数据库

本章节中,我们提供一个上传和保存图片至应用程序数据库的示例。以及,介绍如何在 Jmix 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

如需从用户界面上传文件,请使用 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 bean 下载文件。
2 定义下载后的文件名。
3 如果知道文件格式,可以在 download() 方法的最后一个参数指定。根据格式的不同,浏览器会下载文件或者在标签页展示。