Wednesday, July 17, 2013

Упорядочиваем коллекции в JPA

В JPA есть возможность упорядочивать коллекции сущностей с помощью сравнения значений их полей.
Рассмотрим, как это реализуется.

Возьмем за основу приложение, созданное в посте "JPA-маппинг типов "один-ко-многим" и "многие-к-одному"".

Создадим базу данных jpa_ordering_collections_tutorial с таблицами artists и albums.
Таблица albums имеет колонку album_order, в которой хранятся порядковые номера альбомов по дате выхода, начиная с нуля.
Добавим данные об исполнителе и его альбомах:
CREATE DATABASE jpa_ordering_collections_tutorial;
USE jpa_ordering_collections_tutorial;

CREATE TABLE artists (
artist_id INT PRIMARY KEY,
artist_name VARCHAR(30)
);

CREATE TABLE albums (
album_id INT PRIMARY KEY,
album_name VARCHAR(50), 
album_order INT, 
artist_id INT, 
FOREIGN KEY (artist_id) REFERENCES artists (artist_id)
);

INSERT INTO artists VALUES (1, 'Franz Ferdinand');
INSERT INTO albums VALUES (1, 'Tonight: Franz Ferdinand', 2, 1);
INSERT INTO albums VALUES (2, 'You Could Have It So Much Better', 1, 1);
INSERT INTO albums VALUES (3, 'Franz Ferdinand', 0, 1);

В отличие от приложения, описанного в посте "JPA-маппинг типов "один-ко-многим" и "многие-к-одному"", класс Album не имеет поля year, но имеет поле order:
package com.jpa.ordering.collections.tutorial.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "albums")
public class Album {

    @Id
    @Column(name = "album_id")
    private int id;

    @Column(name = "album_name")
    private String name;

    @Column(name = "album_order")
    private int order;

    @ManyToOne
    @JoinColumn(name = "artist_id")
    private Artist artist;

    public Album() {

    }

    public Album(int id, String name, int order) {
        this.id = id;
        this.name = name;
        this.order = order;
    }

    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 int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public Artist getArtist() {
        return artist;
    }

    public void setArtist(Artist artist) {
        this.artist = artist;
    }

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

Упорядочиваем по идентификатору сущности


Класс Artist аналогичен описанному в посте "JPA-маппинг типов "один-ко-многим" и "многие-к-одному"".
Для того, чтобы упорядочить коллекцию сущностей типа Album по полю id, добавим полю albums аннотацию @OrderBy:
package com.jpa.table.column.mappings.tutorial.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import java.util.List;

@Entity
@Table(name = "artists")
public class Artist {

    @Id
    @Column(name = "artist_id")
    private int id;

    @Column(name = "artist_name")
    private String name;

    @OneToMany(mappedBy = "artist")
    @OrderBy
    private List<Album> albums;

    public Artist() {

    }

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

    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 List<Album> getAlbums() {
        return albums;
    }

    public void setAlbums(List<Album> albums) {
        this.albums = albums;
    }

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

В методе main() класса JpaOrderingCollectionsTutorial создается объект типа ArtistService, вызывается метод для получения сущности Artist и выводится информация об исполнителе и его альбомах:
package com.jpa.ordering.collections.tutorial;

import com.jpa.ordering.collections.tutorial.domain.Album;
import com.jpa.ordering.collections.tutorial.domain.Artist;
import com.jpa.ordering.collections.tutorial.service.ArtistService;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JpaOrderingCollectionsTutorial {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JpaOrderingCollectionsTutorial");
        EntityManager em = emf.createEntityManager();
        ArtistService artistService = new ArtistService(em);

        System.out.println("--- Find artist and order its albums by id ---");
        Artist artist = artistService.findArtist(1);
        System.out.println(String.format("Found artist: %s", artist));
        for (Album album : artist.getAlbums()) {
            System.out.println(String.format("Artist album: %s", album));
        }
    }
}

Запустим метод main():

Приложение вывело информацию об исполнителе и его альбомах, упорядоченных по возрастанию значения поля id.

Упорядочиваем по полю сущности


Для того, чтобы упорядочить коллекцию сущностей типа Album по полю name, укажем это поле и порядок сортировки в качестве значения аннотации @OrderBy.
Для упорядочивания по возрастанию нужно или указать значение "ASC", или вообще не указывать порядок сортировки.
Для упорядочивания по убыванию нужно указать значение "DESC".
Упорядочим коллекцию по возрастанию:
@OrderBy("name ASC")
private List<Album> albums;

Запустим метод main():

Приложение вывело информацию об исполнителе и его альбомах, упорядоченных по возрастанию значения поля name.

Упорядочиваем по колонке таблицы


В таблице albums есть колонка album_order, в которой хранятся порядковые номера альбомов по дате выхода.
Для того, чтобы упорядочить коллекцию сущностей типа Album по их порядковым номерам, добавим полю albums аннотацию @OrderColumn с указанием колонки album_order:
@OrderColumn(name = "album_order")
private List<Album> albums;

Запустим метод main():

Приложение вывело информацию об исполнителе и его альбомах, упорядоченных по значениям колонки order_column, а значит мы успешно реализовали упорядочивание коллекции сущностей с помощью аннотаций @OrderBy и @OrderColumn.


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




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

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

No comments:

Post a Comment