Главная страница
Навигация по странице:

  • Что такое JPQL/HQL и чем он отличается от SQL

  • Что такое Criteria API и для чего он используется

  • 2. EntityGraph Если нужно получить много данных через jpql-запрос, лучше всего использовать EntityGraph.3. @Fetch(FetchMode.SUBSELECT)

  • 5. HibernateSpecificMapping, SqlResultSetMapping Рекомендуется использовать для нативных запросов. Что такое EntityGraph Как и для чего их использовать

  • Subgraph .EntityGraph можно определить с помощью аннотации @NamedEntityGraph

  • Мемоизация

  • Spring Что такое инверсия контроля (IoC) и внедрение зависимостей (DI) Как эти

  • Что такое IoC контейнер

  • Расскажите про ApplicationContext и BeanFactory, чем отличаются В каких

  • Расскажите про аннотацию @Bean

  • @Configuration

  • Чем отличаются аннотации @Bean и @Component

  • Расскажите про аннотации @Service и @Repository. Чем они отличаются

  • PersistenceExceptionTranslationPostProcessor . Расскажите про аннотацию @Autowired

  • Расскажите про аннотацию @Resource

  • Расскажите про аннотацию @Inject

  • Расскажите про аннотацию @Lookup

  • Можно ли вставить бин в статическое поле Почему

  • Расскажите про аннотации @Primary и @Qualifier

  • ОглавлениеCore


    Скачать 1.53 Mb.
    НазваниеОглавлениеCore
    Дата17.05.2023
    Размер1.53 Mb.
    Формат файлаpdf
    Имя файлаpolnaya_metodichka (1).pdf
    ТипДокументы
    #1138113
    страница21 из 25
    1   ...   17   18   19   20   21   22   23   24   25
    READ_ONLY: Используется только для сущностей, которые никогда не изменяются
    (будет выброшено исключение, если попытаться обновить такую сущность). Просто и производительно. Подходит для некоторых статических данных, которые не меняются.

    NONSTRICT_READ_WRITE: Кеш обновляется после совершения транзакции, которая изменила данные в БД и закоммитила их. Таким образом, строгая согласованность не гарантируется, и существует небольшое временное окно между обновлением данных в БД и обновлением тех же данных в кеше, во время которого параллельная транзакция может получить из кеша устаревшие данные.

    READ_WRITE: Гарантирует строгую согласованность, которая достигается за счет
    «мягких» блокировок: когда обновляется кешированная сущность, на нее накладывается мягкая блокировка, которая снимается после коммита транзакции. Все параллельные транзакции, которые пытаются получить доступ к записям в кеше с наложенной мягкой блокировкой, не смогут их прочитать или записать и отправят запрос в БД. Ehcache использует эту стратегию по умолчанию.


    TRANSACTIONAL: полноценное разделение транзакций. Каждая сессия и каждая транзакция видят объекты, словно они работали с ними последовательно одна транзакция за другой. Плата за это – блокировки и потеря производительности.
    Что такое JPQL/HQL и чем он отличается от SQL?
    Hibernate Query Language (HQL) и Java Persistence Query Language (JPQL) являются объектно-ориентированными языками запросов, схожими по природе с SQL. JPQL – это подмножество HQL.
    JPQL – это язык запросов, практически такой же, как SQL, но вместо имен и колонок таблиц базы данных использует имена классов Entity и их атрибуты. В качестве параметров запросов используются типы данных атрибутов Entity, а не полей баз данных. В отличие от
    SQL в JPQL есть автоматический полиморфизм, то есть каждый запрос к Entity возвращает не только объекты этого Entity, но и объекты всех его классов-потомков, независимо от стратегии наследования. В JPA запрос представлен в виде javax.persistence.Query или javax.persistence.TypedQuery, полученных из EntityManager.
    В Hibernate HQL-запрос представлен org.hibernate.query.Query, полученный из Session. Если
    HQL является именованным запросом, то будет использоваться Session#getNamedQuery, в противном случае требуется Session#createQuery.
    Что такое Criteria API и для чего он используется?
    Начиная с версии 5.2, Hibernate Criteria API объявлен deprecated. Вместо него рекомендуется использовать JPA Criteria API.
    JPA Criteria API – это актуальный API, используемый только для выборки (select) сущностей из БД в более объектно-ориентированном стиле.
    Основные преимущества JPA Criteria API:

    ошибки могут быть обнаружены во время компиляции;

    позволяет динамически формировать запросы на этапе выполнения приложения.
    Основные недостатки:

    нет контроля над запросом, сложно отловить ошибку;

    влияет на производительность, множество классов.
    Для динамических запросов фрагменты кода создаются во время выполнения, поэтому JPA
    Criteria API является предпочтительней.
    Н
    екоторые области применения Criteria API:

    поддерживает проекцию, которую можно использовать для агрегатных функций вроде sum(), min(), max() и т. д.;

    может использовать ProjectionList для извлечения данных только из выбранных колонок;

    может быть использована для join запросов с помощью соединения нескольких таблиц, используя методы createAlias(), setFetchMode() и setProjection();

    поддерживает выборку результатов согласно условиям (ограничениям). Для этого используется метод add(), с помощью которого добавляются ограничения
    (Restrictions).


    позволяет добавлять порядок (сортировку) к результату с помощью метода addOrder().
    Расскажите про проблему N+1 Select и путях ее решения
    Проблема N+1 запросов возникает, когда получение данных из БД выполняется за N
    дополнительных SQL-запросов для извлечения тех же данных, которые могли быть получены при выполнении основного SQL-запроса.
    1. JOIN FETCH
    И при FetchType.EAGER, и при FetchType.LAZY поможет JPQL-запрос с JOIN FETCH. Опцию
    «FETCH» можно использовать в JOIN (INNER JOIN или LEFT JOIN) для выборки связанных объектов в одном запросе вместо дополнительных запросов для каждого доступа к ленивым полям объекта.
    Лучший вариант решения для простых запросов (1-3 уровня вложенности связанных объектов).
    select pc
    from PostComment pc
    join fetch pc.post p
    2. EntityGraph
    Если нужно получить много данных через jpql-запрос, лучше всего использовать EntityGraph.
    3. @Fetch(FetchMode.SUBSELECT)
    Аннотация Hibernate. Можно использовать только с коллекциями. Будет сделан один sql- запрос для получения корневых сущностей и, если в контексте персистентности будет обращение к ленивым полям-коллекциям, то выполнится еще один запрос для получения связанных коллекций:
    @Fetch(value = FetchMode.SUBSELECT)
    private Set orders = new HashSet<>();
    4. Batch fetching
    Аннотация Hibernate, в JPA ее нет. Указывается над классом сущности или над полем коллекции с ленивой загрузкой. Будет сделан один sql-запрос для получения корневых сущностей и, если в контексте персистентности будет обращение к ленивым полям- коллекциям, то выполнится еще один запрос для получения связанных коллекций.
    Количество загружаемых сущностей указывается в аннотации.
    @BatchSize(size=5)
    private Set orders = new HashSet<>();
    5. HibernateSpecificMapping, SqlResultSetMapping
    Рекомендуется использовать для нативных запросов.
    Что такое EntityGraph? Как и для чего их использовать?
    Основная цель JPA Entity Graph – улучшить производительность в рантайме при загрузке базовых полей сущности и связанных сущностей и коллекций.

    Hibernate загружает весь граф в одном SELECT-запросе, то есть все указанные связи от нужной сущности. Если необходимо загрузить дополнительные сущности, находящиеся в связанных сущностях, используется Subgraph.
    EntityGraph можно определить с помощью аннотации @NamedEntityGraph для Entity, она определяет уникальное имя и список атрибутов (attributeNodes), которые должны быть загружены с использованеим entityManager из JPA API:
    EntityGraph entityGraph = entityManager.createEntityGraph(Post.class);
    entityGraph.addAttributeNodes("subject");
    entityGraph.addAttributeNodes("user");
    entityGraph.addSubgraph("comments").addAttributeNodes("user");
    JPA определяет два свойства или подсказки, с помощью которых Hibernate может выбирать стратегию извлечения графа сущностей во время выполнения:

    fetchgraph – все атрибуты, перечисленные в EntityGraph, меняют fetchType на
    EAGER, все остальные – на LAZY;

    loadgraph – все атрибуты, перечисленные в EntityGraph, меняют fetchType на EAGER,
    все остальные сохраняют свой fetchType. С помощью NamedSubgraph можно изменить fetchType вложенных объектов Entity.
    Загрузить EntityGraph можно тремя способами:
    1. Используя перегруженный метод find(), который принимает Map с настройками
    EntityGraph.
    2. Используя JPQL и передав подсказку через setHint().
    3. С помощью Criteria API.
    Мемоизация
    Memoization – вариант кеширования, заключающийся в том, что для функции создается таблица результатов. Результат функции, вычисленной при определенных значениях параметров, заносится в эту таблицу. В дальнейшем результат берется из данной таблицы.
    Эта техника позволяет за счет использования дополнительной памяти ускорить работу программы.
    Можно применить только к функциям, которые являются:

    детерминированными (т. е. при одном и том же наборе параметров функции должны возвращать одинаковое значение);

    без побочных эффектов (т. е. не должны влиять на состояние системы).
    В Java наиболее подходящей кандидатурой на роль хранилища является интерфейс Map.
    Сложность операций get,put,contains равна O(1). Это позволяет гарантировать ограничение задержки при выполнении мемоизации.
    Мемоизация реализована в библиотеке ehcache.

    Spring
    Что такое инверсия контроля (IoC) и внедрение зависимостей (DI)? Как эти
    принципы реализованы в Spring?
    Inversion of Control – подход, который позволяет конфигурировать и управлять объектами
    Java с помощью рефлексии. Вместо ручного внедрения зависимостей фреймворк забирает ответственность за это через IoC-контейнер. Контейнер отвечает за управление жизненным циклом объектов: создание объектов, вызов методов инициализации и конфигурирование объектов через связывание их между собой.
    Объекты, создаваемые контейнером, называются beans. Конфигурирование контейнера осуществляется через внедрение аннотаций, но есть возможность, по старинке, загрузить
    XML-файлы, содержащие определение bean’ов и предоставляющие информацию,
    необходимую для создания bean’ов.
    Dependency Injection является одним из способов реализации принципа IoC в Spring. Это шаблон проектирования, в котором контейнер передает экземпляры объектов по их типу другим объектам с помощью конструктора или метода класса (setter), что позволяет писать слабосвязный код.
    Что такое IoC контейнер?
    В среде Spring IoC-контейнер представлен интерфейсом ApplicationContext, который является оберткой над BeanFactory, предоставляющей дополнительные возможности,
    например AOP и транзакции. Интерфейс BeanFactory предоставляет фабрику для бинов,
    которая в то же время является IoC-контейнером приложения. Управление бинами основано на конфигурации (аннотации или xml). Контейнер создает объекты на основе конфигураций и управляет их жизненным циклом от создания объекта до уничтожения.
    Расскажите про ApplicationContext и BeanFactory, чем отличаются? В каких
    случаях что стоит использовать?
    ApplicationContext является наследником BeanFactory и полностью реализует его функционал, добавляя больше специфических enterprise-функций. Может работать с бинами всех скоупов.
    BeanFactory – это фактический контейнер, который создает, настраивает и управляет рядом bean-компонентов. Эти бины обычно взаимодействуют друг с другом и имеют зависимости между собой. Эти зависимости отражены в данных конфигурации, используемых
    BeanFactory. Может работать с бинами singleton и prototype.

    BeanFactory обычно используется тогда, когда ресурсы ограничены (мобильные устройства),
    так как он легче по сравнению с ApplicationContext. Поэтому, если ресурсы не сильно ограничены, то лучше использовать ApplicationContext.
    ApplicationContext загружает все бины при запуске, а BeanFactory по требованию.
    Расскажите про аннотацию @Bean?
    Аннотация @Bean используется для указания того, что метод создает, настраивает и инициализирует новый объект, управляемый IoC-контейнером. Такие методы можно использовать как в классах с аннотацией @Configuration, так и в классах с аннотацией
    @Component (или ее наследниках).
    Имеет следующие свойства:

    destroyMethod, initMethod – варианты переопределения методов инициализации и удаления бина при указании их имен в аннотации;

    name – имя бина, по умолчанию именем бина является имя метода;

    value – алиас для name().
    Расскажите про аннотацию @Component?
    @Component используется для указания класса в качестве компонента Spring. Такой класс будет сконфигурирован как spring Bean.
    Чем отличаются аннотации @Bean и @Component?
    @Bean ставится над методом и позволяет добавить bean, уже реализованного сторонней библиотекой класса, в контейнер, а @Component используется для указания класса,
    написанного программистом.
    Расскажите про аннотации @Service и @Repository. Чем они отличаются?
    @Repository указывает, что класс используется для работы с поиском, получением и хранением данных. Аннотация может использоваться для реализации шаблона DАО.
    @Service указывает, что класс является сервисом для реализации бизнес-логики.
    @Repository, @Service, @Controller и @Configuration являются алиасами @Component, их также называют стереотипными аннотациями.
    Задача @Repository заключается в том, чтобы отлавливать определенные исключения персистентности и пробрасывать их как одно непроверенное исключение Spring Framework.
    Для этого в
    контекст должен быть добавлен класс
    PersistenceExceptionTranslationPostProcessor.
    Расскажите про аннотацию @Autowired
    @Autowired – автоматическое внедрение подходящего бина:
    1. Контейнер определяет тип объекта для внедрения.
    2. Контейнер ищет соответствующий тип бина в контексте (он же контейнер).
    3. Если есть несколько кандидатов и один из них помечен как @Primary, то внедряется он.

    4. Если используется @Qualifier, то контейнер будет использовать информацию из
    @Qualifier, чтобы понять, какой компонент внедрять.
    5. В противном случае контейнер внедрит бин, основываясь на его имени или ID.
    6. Если ни один из способов не сработал, то будет выброшено исключение.
    Контейнер обрабатывает DI с помощью AutowiredAnnotationBeanPostProcessor. В связи с этим аннотация не может быть использована ни в одном BeanFactoryPP или BeanPP.
    В аннотации есть один параметр required = true/fals. Он указывает, обязательно ли делать DI.
    По умолчанию true. Либо можно не выбрасывать исключение, а оставить поле c null, если нужный бин не был найден – false.
    При циклической зависимости, когда объекты ссылаются друг на друга, нельзя ставить над конструктором.
    Однако при внедрении прямо в поля не нужно предоставлять прямого способа создания экземпляра класса со всеми необходимыми зависимостями. Это означает, что:

    существует способ (через вызов конструктора по умолчанию) создать объект с использованием new в состоянии, когда ему не хватает некоторых из его обязательных зависимостей, и использование приведет к NullPointerException;

    такой класс не может быть использован вне DI-контейнеров (тесты, другие модули) и нет способа кроме рефлексии предоставить ему необходимые зависимости;

    неизменность;
    В отличие от способа с использованием конструктора внедрение через поля не может использоваться для присвоения зависимостей final-полям, что приводит к тому, что объекты становятся изменяемыми.
    Расскажите про аннотацию @Resource
    @Resource (аннотация java) пытается получить зависимость: по имени, по типу, затем по описанию (Qualifier). Имя извлекается из имени аннотируемого сеттера или поля либо берется из параметра name.
    @Resource //По умолчанию поиск бина с именем "context"
    private ApplicationContext context;
    @Resource(name="greetingService") //Поиск бина с именем "greetingService"
    public void setGreetingService(GreetingService service) {
    this.greetingService = service;
    }
    Отличие от
    @Autowired:

    ищет бин сначала по имени, а потом по типу;

    не нужна дополнительная аннотация для указания имени конкретного бина;


    @Autowired позволяет отметить место вставки бина как необязательное
    @Autowired(required = false);

    при замене Spring Framework на другой фреймворк менять аннотацию @Resource не нужно.
    Расскажите про аннотацию @Inject
    @Inject входит в пакет javax.inject. Чтобы ее использовать, нужно добавить зависимость:

    javax.inject
    javax.inject
    1

    @Inject (аннотация java) – аналог @Autowired (аннотация spring) в первую очередь пытается подключить зависимость по типу, затем по описанию и только потом по имени. В ней нет параметров. Поэтому при использовании конкретного имени (Id) бина используется @Named:
    @Inject
    @Named("yetAnotherFieldInjectDependency")
    private ArbitraryDependency yetAnotherFieldInjectDependency;
    Расскажите про аннотацию @Lookup
    Обычно бины в приложении Spring являтся синглтонами и для внедрения зависимостей используется конструктор или сеттер.
    Но бывает и другая ситуация: имеется бин Car – синглтон (singleton bean) – и ему требуется каждый раз новый экземпляр бина Passenger. То есть Car – синглтон, а Passenger – так называемый прототипный бин (prototype bean). Жизненные циклы бинов разные. Бин Car создается контейнером только раз, а бин Passenger создается каждый раз новый. Допустим,
    это происходит каждый раз при вызове какого-то метода бина Car. Вот здесь и пригодится внедрение бина с помощью метода Lookup. Оно происходит не при инициализации контейнера, а позднее: каждый раз, когда вызывается метод. Суть в том, что создается метод-заглушка в бине Car и он помечается специальным образом – аннотацией @Lookup.
    Этот метод должен возвращать бин Passenger, каждый раз новый. Контейнер Spring под капотом создаст подкласс и переопределит этот метод и будет выдавать новый экземпляр бина Passenger при каждом вызове аннотированного метода. Даже если в заглушке он возвращает null (а так и надо делать, все равно этот метод будет переопределен).
    Можно ли вставить бин в статическое поле? Почему?
    Spring не позволяет внедрять бины напрямую в статические поля. Это связано с тем, что когда загрузчик классов загружает статические значения, контекст Spring еще не загружен.
    Чтобы исправить это, можно создать нестатический сеттер-метод с @Autowired:
    private static OrderItemService orderItemService;
    @Autowired

    public void setOrderItemService(OrderItemService orderItemService) {
    TestDataInit.orderItemService = orderItemService;
    }
    Расскажите про аннотации @Primary и @Qualifier
    @Qualifier применяется, если кандидатов для автоматического связывания несколько,
    аннотация позволяет указать в качестве аргумента имя конкретного бина, который следует внедрить. Она может быть применена к отдельному полю класса, к отдельному аргументу метода или конструктора:
    public class AutowiredClass {
    @Autowired //к полям класса
    @Qualifier("main")
    private GreetingService greetingService;
    @Autowired //к отдельному аргументу конструктора или метода
    public void prepare(@Qualifier("main") GreetingService greetingService){
    /* что-то делаем... */
    };
    }
    Поэтому у одной из реализации
    1   ...   17   18   19   20   21   22   23   24   25


    написать администратору сайта