Pages

Monday, November 3, 2014

Основы Hibernate

Hibernate - популярный ORM-фреймворк, который предоставляет возможность сохранять Java-объекты в базе данных.
Он является самой популярной реализацией JPA.

Ранее мы разобрали основы JPA, а сейчас создадим простое приложение с использованием Hibernate.

Для этого нам понадобятся следующие технологии:
  • Hibernate 4.3.6
  • MySQL 5.6.14
  • Maven 3.1.1

Создадим базу данных hibernate_basics_tutorial и таблицу artist с колонками id, name и genre.
Таблица будет хранить информацию о музыкальных исполнителях:
CREATE DATABASE hibernate_basics_tutorial;
USE hibernate_basics_tutorial;

CREATE TABLE artist (
id INT PRIMARY KEY,
name VARCHAR(30),
genre VARCHAR(20)
);

Добавим в файл pom.xml необходимые зависимости:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>hibernate-basics-tutorial</groupId>
    <artifactId>hibernate-basics-tutorial</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.6.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.33</version>
        </dependency>
    </dependencies>

</project>

Создадим класс Artist с полями id, name и genre.
Класс, с которым может работать Hibernate, называется сущностью (entity).
Для того, чтобы класс Artist стал сущностью, добавим аннотацию @Entity.
Сущности типа Artist будут храниться в таблице, имя которой совпадает с именем класса, т.е. artist.
Значения полей сущностей будут храниться в одноименных колонках этой же таблицы.
Сущность должна иметь persistence identity, или идентификатор. Это - ключ, который уникально ее идентифицирует и выделяет среди других сущностей такого же типа. Идентификатор указывается с помощью аннотации @Id. В классе Artist в качестве идентификатора можно использовать поле id, которое соответствует колонке первичного ключа в таблице artist:
package com.hibernate.basics.tutorial.domain;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Artist {

    @Id
    private int id;

    private String name;
    private String genre;

    public Artist() {

    }

    public Artist(int id, String name, String genre) {
        this.id = id;
        this.name = name;
        this.genre = genre;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGenre() {
        return genre;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    @Override
    public String toString() {
        return "Artist{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", genre='" + genre + '\'' +
                '}';
    }
}

Создадим класс ArtistService, который имеет:
  • поле session типа Session, который реализует API для работы с сущностями. Метод save() создает новую сущность, get() производит поиск сущности, delete() удаляет сущность, а createQuery() позволяет выполнять HQL-запросы. Для изменения сущности не нужно вызывать специальный метод Session, достаточно изменить значение поля сущности (например, с помощью метода setGenre())
  • CRUD-методы (Create, Read, Update, Delete), которые используют Session для создания, чтения, изменения и удаления сущностей
package com.hibernate.basics.tutorial.service;

import com.hibernate.basics.tutorial.domain.Artist;
import org.hibernate.Query;
import org.hibernate.Session;

import java.util.List;

public class ArtistService {

    private Session session;

    public ArtistService(Session session) {
        this.session = session;
    }

    public Artist createArtist(int id, String name, String genre) {
        Artist artist = new Artist(id, name, genre);
        session.save(artist);
        return artist;
    }

    public void removeArtist(int id) {
        Artist artist = (Artist) session.get(Artist.class, id);

        if (artist != null) {
            session.delete(artist);
        }
    }

    public Artist changeArtistGenre(int id, String genre) {
        Artist artist = (Artist) session.get(Artist.class, id);

        if (artist != null) {
            artist.setGenre(genre);
        }

        return artist;
    }

    public Artist findArtist(int id) {
        return (Artist) session.get(Artist.class, id);
    }

    public List<Artist> findAllArtists() {
        Query query = session.createQuery("SELECT a FROM Artist a");
        return query.list();
    }
}

Session создается с помощью объекта типа SessionFactory.
Настройки для создания объекта SessionFactory хранятся в файле hibernate.cfg.xml, который должен находиться в директории resources.
Создадим этот файл и укажем настройки для соединения с базой данных и перечислим классы наших сущностей (в данном случае - Artist):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_basics_tutorial</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.connection.username">root</property>
        <mapping class="com.hibernate.basics.tutorial.domain.Artist"/>
    </session-factory>
</hibernate-configuration>

Создадим класс HibernateBasicsTutorial для проверки работы приложения.
В методе main() создаются объекты SessionFactory, Session и ArtistService, после чего вызываются CRUD-методы.
Для того, чтобы действия над сущностями сохранялись в базе данных, методы для создания, изменения и удаления сущностей должны вызываться в транзакциях. Для открытия и закрытия транзакций используются методы beginTransaction() и commit() объекта Transaction:
package com.hibernate.basics.tutorial;

import com.hibernate.basics.tutorial.domain.Artist;
import com.hibernate.basics.tutorial.service.ArtistService;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

import java.util.List;

public class HibernateBasicsTutorial {

    public static void main(String[] args) {
        Configuration configuration = new Configuration().configure();
        StandardServiceRegistry serviceRegistry =
                new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        Session session = sessionFactory.openSession();
        ArtistService service = new ArtistService(session);

        System.out.println("--- Create and persist artist ---");
        Transaction transaction = session.beginTransaction();
        Artist artist = service.createArtist(1, "Franz Ferdinand", "Rock");
        transaction.commit();
        System.out.println(String.format("Persisted: %s\n", artist));

        System.out.println("--- Find artist ---");
        artist = service.findArtist(1);
        System.out.println(String.format("Found: %s\n", artist));

        System.out.println("--- Find all artists ---");
        List<Artist> artists = service.findAllArtists();
        for (Artist foundArtist : artists) {
            System.out.println(String.format("Found: %s\n", foundArtist));
        }

        System.out.println("--- Update artist ---");
        transaction = session.beginTransaction();
        artist = service.changeArtistGenre(1, "Indie Rock");
        transaction.commit();
        System.out.println(String.format("Updated: %s\n", artist));

        System.out.println("--- Remove artist ---");
        transaction = session.beginTransaction();
        service.removeArtist(1);
        transaction.commit();
        artist = service.findArtist(1);
        System.out.println(String.format("Found: %s\n", artist));

        session.close();
        sessionFactory.close();
    }
}

Запустим метод main():
--- Create and persist artist ---
Persisted: Artist{id=1, name='Franz Ferdinand', genre='Rock'}

--- Find artist ---
Found: Artist{id=1, name='Franz Ferdinand', genre='Rock'}

--- Find all artists ---
Found: Artist{id=1, name='Franz Ferdinand', genre='Rock'}

--- Update artist ---
Updated: Artist{id=1, name='Franz Ferdinand', genre='Indie Rock'}

--- Remove artist ---
Found: null

Все CRUD-методы отработали верно, а это значит, что мы успешно использовали Hibernate в приложении.

Структура проекта:

























Исходный код созданного приложения доступен по ссылке https://code.google.com/p/hibernate-basics-tutorial/.

Рекомендуемые посты:

1 comment:

  1. Отличный урок, только artist - это художник) Спасибо большое)

    ReplyDelete