6.1 Храним файлы на сервере

Иногда в базу данных нужно сохранить бинарные объекты. Например, файлы. Если файл большой, то разумнее всего хранить его в отдельной папке на диске, а в базе данных хранить его пути. Пример:

c:\db-files\users\12355\avatar.jpg

И в базе храним просто относительный путь к файлу:

\12355\avatar.jpg

В базе удобно хранить относительный путь, так как из него потом легко получить URL:

https://storage.javarush.ru/users/12355/avatar.jpg

Мы просто приклеиваем относительный путь к имени сервера и готово.

6.2 Храним картинки прямо в базе

Однако, если картинки маленькие, их можно хранить прямо в базе и отдавать клиенту как набор байт. Для таких случаем в SQL есть специальный тип данных BLOB – Binary Large Object. Вернее, их даже два:

  • CLOB – Character Large Object,
  • BLOB – Binary Large Object.

CLOB используется для хранения очень больших текстов. А BLOB для хранения бинарных данных, таких как небольшие картинки, видео и тому подобное.

Пример:

@Entity
@Table(name="user")
public class User {

    @Id
    private String id;

	@Column(name = "name", columnDefinition="VARCHAR(128)")
    private String name;

	@Lob
	@Column(name = "photo", columnDefinition="BLOB")
    private byte[] photo;

	// ...
}

Аннотация @Lob подсказывает Hibernate, что в поле хранится Large Object. А columnDefinition="BLOB" уже говорит о том, как это все сохранить в базе.

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

byte[] imageBuffer = Files.readAllBytes(Paths.get("C:/temp/avatar.png"))

User user = new User();
user.setId("1");
user.setName("Zapp");
user.setPhoto(imageBuffer);

session.persist(user);

6.3 XML и JSON

Hibernate имеет интересную поддержку JSON в качестве типа данных. Он позволяет сохранить HashMap строк в виде единого JSON-объекта. Если СУБД умеет работать с JSON, то выглядит это так:

@JdbcTypeCode(SqlTypes.JSON)
private Map<String, String> properties;

Hibernate берет на себя заботу, чтобы объект типа Map<String, String> был сериализован в единый JSON-объект. Также при чтении объекта из базы превращает JSON-объект в набор Map<String, String>.

Нечто похожее Hibernate может проделать и с XML:

@JdbcTypeCode(SqlTypes.SQLXML)
private Map<String, String> properties;