1.4.2. Создание сервиса для извлечения данных

В данном разделе мы создадим сервис, позволяющий извлечь из базы данные для построения диаграмм.

  1. Один из методов сервиса будет возвращать список неперсистентных сущностей, поэтому начнем с создания и регистрации класса этой сущности.

    Создайте в пакете com.sample.library.entity модуля global класс BooksByGenre:

    package com.sample.library.entity;
    
    import com.haulmont.chile.core.annotations.MetaClass;
    import com.haulmont.chile.core.annotations.MetaProperty;
    import com.haulmont.cuba.core.entity.AbstractNotPersistentEntity;
    
    @MetaClass(name = "library$BooksByGenre")
    public class BooksByGenre extends AbstractNotPersistentEntity {
    
        @MetaProperty
        private String genre;
    
        @MetaProperty
        private Long countOfBooks;
    
        public String getGenre() {
            return genre;
        }
    
        public void setGenre(String genre) {
            this.genre = genre;
        }
    
        public Long getCountOfBooks() {
            return countOfBooks;
        }
    
        public void setCountOfBooks(Long countOfBooks) {
            this.countOfBooks = countOfBooks;
        }
    }
    

    Экземпляр этого класса содержит количество книг определенного жанра. Далее необходимо зарегистрировать класс сущности в файле metadata.xml модуля global:

    <metadata-model root-package="com.sample.library">
            <class>com.sample.library.entity.BooksByGenre</class>
        </metadata-model>
  2. Для создания интерфейса и класса сервиса можно воспользоваться CUBA Studio. Для этого откройте вкладку Services на панели навигатора и нажмите на кнопку New. В открывшемся окне установите в поле Interface значение com.sample.library.service.StatisticsService. В полях Bean и Service name будут сгенерированы подходящие значения com.sample.library.service.StatisticsServiceBean и library_StatisticsService соответственно. Сохраните изменения.

    Откройте интерфейс сервиса StatisticsService в IDE и объявите в нем методы получения данных из базы:

    package com.sample.library.service;
    
    import com.sample.library.entity.BooksByGenre;
    import java.util.List;
    import java.util.Map;
    
    public interface StatisticsService {
        String NAME = "library_StatisticsService";
    
        public List<BooksByGenre> getCountOfBooksByGenre();
    
        public List<String> getTopPublishers(int count);
    
        public Map<Integer, Map<String, Long>> getCountOfBooksByPublisherAndYear();
    }
    
  3. Далее откройте класс сервиса StatisticsServiceBean и замените его содержимое на следующий код:

    package com.sample.library.service;
    
    import com.google.common.collect.Lists;
    import com.haulmont.cuba.core.EntityManager;
    import com.haulmont.cuba.core.Persistence;
    import com.haulmont.cuba.core.Transaction;
    import com.sample.library.entity.BooksByGenre;
    import org.springframework.stereotype.Service;
    
    import javax.inject.Inject;
    import java.util.ArrayList;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    
    @Service(StatisticsService.NAME)
    public class StatisticsServiceBean implements StatisticsService {
    
        @Inject
        private Persistence persistence;
    
    
        @Override
        public List<BooksByGenre> getCountOfBooksByGenre() {
            List<BooksByGenre> result = new ArrayList<>();
            String query = "select ltype.name, count(book) " +
                           "from library$Book book join book.literatureType ltype " +
                           "group by ltype.name order by ltype.name";
            Transaction transaction = persistence.createTransaction();
            try {
                EntityManager em = persistence.getEntityManager();
                List<Object[]> resultList = em.createQuery(query, Object[].class).getResultList();
    
                for (Object[] row : resultList) {
                    BooksByGenre entity = new BooksByGenre();
                    entity.setGenre((String) row[0]);
                    entity.setCountOfBooks((Long) row[1]);
                    result.add(entity);
                }
            } finally {
                transaction.end();
            }
    
            return result;
        }
    
        @Override
        public List<String> getTopPublishers(final int count) {
            List<String> result = Lists.newArrayList();
            String query = "select instance.bookPublication.publisher.name, count(instance) " +
                    "from library$BookInstance instance " +
                    "group by instance.bookPublication.publisher.name order by count(instance) desc";
            Transaction transaction = persistence.createTransaction();
            try {
                EntityManager em = persistence.getEntityManager();
                List resultList = em.createQuery(query).getResultList();
    
                for (int i = 0; i < resultList.size(); i++) {
                    if (i == count) {
                        break;
                    }
                    Object[] data = (Object[]) resultList.get(i);
                    result.add((String) data[0]);
                }
            } finally {
                transaction.end();
            }
    
            return result;
        }
    
        @Override
        public Map<Integer, Map<String, Long>> getCountOfBooksByPublisherAndYear() {
            Map<Integer, Map<String, Long>> result = new LinkedHashMap<>();
            String query = "select instance.bookPublication.publisher.name, instance.bookPublication.year, count(instance) " +
                    "from library$BookInstance instance " +
                    "group by instance.bookPublication.year, instance.bookPublication.publisher.name " +
                    "order by instance.bookPublication.year, instance.bookPublication.publisher.name";
            Transaction transaction = persistence.createTransaction();
            try {
                EntityManager em = persistence.getEntityManager();
                List resultList = em.createQuery(query).getResultList();
    
                for (Object row : resultList) {
                    Object[] data = (Object[]) row;
    
                    String publisher = (String) data[0];
                    Integer year = (Integer) data[1];
                    Long quantity = (Long) data[2];
    
                    if (result.get(year) == null) {
                        result.put(year, new LinkedHashMap<String, Long>());
                    }
                    result.get(year).put(publisher, quantity);
                }
            } finally {
                transaction.end();
            }
    
            return result;
        }
    }
    

    Метод getCountOfBooksByGenre() возвращает количество книг каждого жанра в виде списка сущностей BooksByGenre. Метод getTopPublishers(int count) сортирует издателей по убыванию количества экземпляров выпущенных ими книг, находящихся в библиотеке, и возвращает первые count издателей. Метод getCountOfBooksByPublisherAndYear() возвращает количество книг, выпущенных издателями в определенном году.