6.1 Armazenar arquivos no servidor
Às vezes, objetos binários precisam ser salvos no banco de dados. Por exemplo, arquivos. Se o arquivo for grande, é mais razoável armazená-lo em uma pasta separada no disco e armazenar seus caminhos no banco de dados. Exemplo:
c:\db-files\users\12355\avatar.jpg
E no banco de dados armazenamos apenas um caminho relativo para o arquivo:
\12355\avatar.jpg
É conveniente armazenar um caminho relativo no banco de dados, pois é fácil obter uma URL a partir dele:
https://storage.codegym.cc/users/12355/avatar.jpg
Apenas colamos o caminho relativo ao nome do servidor e pronto.
6.2 Armazenar imagens diretamente no banco de dados
No entanto, se as imagens forem pequenas, elas podem ser armazenadas diretamente no banco de dados e fornecidas ao cliente como um conjunto de bytes. Para tais casos, o SQL possui um tipo de dados BLOB especial - Binary Large Object. Ou melhor, existem até dois deles:
- CLOB - Personagem Grande Objeto,
- BLOB - Objeto Binário Grande.
CLOB é usado para armazenar textos muito grandes. Um BLOB serve para armazenar dados binários, como pequenas imagens, vídeos e similares.
Exemplo:
@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;
// ...
}
A anotação @Lob
informa ao Hibernate que um Objeto Grande está armazenado no campo . E columnDefinition="BLOB"
já fala como salvar tudo no banco de dados.
Vamos escrever um código de exemplo que salva um novo usuário e sua foto no banco de dados:
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 e JSON
O Hibernate tem um suporte interessante para JSON como um tipo de dados. Ele permite que você armazene um HashMap de strings como um único objeto JSON. Se o DBMS puder funcionar com JSON, ele ficará assim:
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, String> properties;
O Hibernate cuida para que o objeto de tipo Map<String, String>
seja serializado em um único objeto JSON. Além disso, ao ler um objeto do banco de dados, ele transforma o objeto JSON em um conjunto de arquivos Map<String, String>
.
O Hibernate pode fazer algo semelhante com XML:
@JdbcTypeCode(SqlTypes.SQLXML)
private Map<String, String> properties;