1. Зберігаємо файли на сервері

Іноді в базі даних потрібно зберегти бінарні об'єкти. Наприклад, файли. Якщо файл великий, то розумніше зберігати його в окремій папці на диску, а в базі даних зберігати його шляхи. Приклад:

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

І в базі зберігаємо просто відносний шлях до файлу:

\12355\avatar.jpg

У базі зручно зберігати відносний шлях, тому що з нього потім легко отримати URL:

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

Ми просто приклеюємо відносний шлях до імені сервера — і готово.

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);

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;