1. Запрос объекта объекта
Запрос объекта объекта является основой запроса HQL. В качестве языка объекта, он отличается от SQL во время операций запроса. Контент в строке запроса должен быть заменен на имя класса и имя атрибута класса. Этот метод запроса относительно прост. Пока у вас есть навыки SQL, очень просто использовать HQL. Тем не менее, есть некоторые проблемы, на которые необходимо обратить внимание, то есть запрос и получение данных не является целью, и то, что необходимо учитывать, - это то, как писать эффективные операторы запроса, что является в центре внимания обсуждения.
1.n+1 проблема
(1) В чем проблема N+1
Когда я впервые услышал это существительное, у меня могут возникнуть сомнения. Я никогда раньше не слышал о проблеме n+1. Так что это значит? N+1 относится к N данных в таблице, поэтому при получении этих N данных будет сгенерирована команда N+1 SQL. Эта операция называется n+1. Здесь 1 ссылается на выпуск заявления, который ищет список идентификации, и N относится к выдаче операторов N SQL на основе идентификатора для загрузки связанных объектов. Этот вид операции запроса очень неэффективен и часто генерируется в итераторах. То есть, если мы напрямую преобразуем результаты запроса в итераторы, эта проблема возникнет следующим образом:
public void testquery () {session session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); /*** Будет проблема n+1. Так называемая стоимость N+1-это выпустить операторы n+1 SQL** 1: Выпустите утверждение, которое запрашивает список идентификации** n: выпуск n SQL-операторы на основе идентификатора и загрузите соответствующий объект*/ iterator iter = session.createequery («от студента»). Itrate (); while (iter.hasnext ()) {студент студента = (студент) iter.next (); System.out.println (Student.getName ()); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}Приведенный выше код запроса приведет к проблеме n+1, поскольку запрос возвращается как итератор, так что будет выдан оператор SQL, если он не будет генерироваться один раз. Это в основном зависит от механизма запроса итератора, который запрашивает данные из кэша. Если данные не существует в кэше, данные сначала будут преобразованы в память, поэтому в настоящее время будет выпущена оператор SQL -запроса, поэтому каждую итерацию будет создан оператор SQL. Этот метод написания на самом деле является ошибкой и может быть решен с использованием других методов для оптимизации.
(2) Избегайте проблемы N+1
Проблема n+1 возникает из -за неправильного использования итерации. Конечно, другие методы могут быть использованы, чтобы избежать этой проблемы n+1. Вот метод списка. Самая большая разница между списком и итерацией заключается в том, что список помещает данные в кэш, но не использует кэш. По умолчанию список будет выпускать операторы SQL каждый раз. Перед использованием Itater вы можете использовать список для сохранения данных в базе данных, чтобы итерация могла читать из кэша при доступе к данным, избегая возникновения проблем N+1. Код заключается в следующем:
public void testquery () {session session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); Список студентов = session.createquery ("от студента"). List (); System.out.println ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Затем не выдается оператор SQL, основанные на ID, и данные в кэше используются непосредственно * * Метод итерации, если данные существуют в кэше, это может улучшить производительность, в противном случае возникают проблемы n+1 */ // Вы можете использовать AS ASTERTATOR ITERATO System.out.println (Student.getName ()); }}Приведенный выше пример избегает проблемы N+1, потому что после выполнения операции списка данные будут размещены в кэше сеанса (кэш первого уровня). Следовательно, при использовании Itater будет выдан оператор для запроса списка идентификаторов, а затем соответствующие данные будут загружены в кэше в соответствии с идентификатором. Если в кэше есть данные, соответствующие данным, запрос оператора SQL, основанный на идентификаторе, больше не будет выпущен, и данные в кэше будут использованы непосредственно. Метод итерации может повысить производительность, если в кеше существуют данные, в противном случае возникнут проблемы n+1.
2. Запрос навигации объекта
Навигация объекта относится к получению данных из другого объекта в соответствии с навигацией атрибутов объекта в одном объекте. Это может упростить операторы запроса и оптимизировать методы запроса. Если мы следим за нашими обычными идеями, мы можем переписать и написать объект другого класса, чтобы получить работу другого объекта, который более громоздкий для сравнения оператора навигации объекта.
@Suppresswarnings ({"unchecked", "rawtypes"}) public void testquery1 () {session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); // Возврат списка атрибутов набора результатов, тип элемента и типы атрибутов в классе объектов - это один и тот же список студентов = session.createequery («От студента s, где s.classes.name, как«%2%'»). List (); for (iterator item = studies.iterator (); ite.hasnext ();) {Студент obj = (студент) ite.next (); System.out.println (obj.getName ()); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}Оператор запроса в приведенном выше примере использует метод навигации объекта. Заявление запроса - это информационный запрос от объекта студента, но атрибуты объекта, которые будут сравниваться, исходят из атрибута имени объекта классов. В настоящее время использование метода запроса на навигацию объекта значительно повысит эффективность запроса и оптимизирует оператор запроса. Если бы это был обычный метод запроса, может быть сгенерировано большое количество операторов подключения, что очень сложно.
2. Несоответствующий запрос SQL
Значение собственного запроса заключается в использовании операторов SQL для запроса и получения данных, а не использование операторов HQL. Его метод использования на самом деле очень прост, похожий на HQL. Вам нужно только использовать метод CreateSqlQuery для запроса. На самом деле это похоже на метод CreateQuery HQL. Код заключается в следующем:
public void testqeury () {session session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); Список списка = session.createSqlquery ("select * from t_student"). List (); for (iterator item = list.iterator (); ite.hasnext ();) {object [] obj = (object []) ite.next (); System.out.println (obj [0]+","+obj [1]); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}Приведенный выше код использует метод CreateSqlQuery. Строка запроса в методе является оператором SQL. Он реализует базовый метод строкового запроса. Разница в том, что HQL имеет еще один уровень упаковки и настраивает соответствующие параметры диалекта в hibernate.cfg.xml для завершения картирования.
3. Подключение запрос
Запросы подключения часто используются в SQL для получения коллекции нескольких объектов. Среди них наиболее часто используемыми являются внутреннее соединение, левое соединение, правое соединение и т. Д., Которые относятся к запросу внутреннего соединения, запрос на внешний соединение и справочный внешний вопрос. Контент, который они возвращают во время запроса, - это картезианский продукт между сущностями, содержание запроса и некоторое содержание левой таблицы, содержание запроса и некоторое содержание правой таблицы и функция запроса является мощной. Метод запроса подключения HQL и запрос на соединение SQL одинаковы в результатах запроса, но в операторах запросов существуют небольшие различия.
1. Внутренняя связь
Внутренний запрос HQL может быть запрошен с использованием оператора INNER JOIN или оператора JOIN, а полученным набором результатов является картезианский продукт. Подобно запросу внутри соединения SQL, запрос соединения HQL разделен на два типа: явные и неявные. Отображаемый запрос относится к ключевому слову соединения в строке запроса. Неявный запрос не должен добавлять соединение в строку.
// внутреннее соединение @suppresswarnings ({"unchecked", "ravtypes"}) public void testquery () {session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); // возвращать список атрибутов набора результатов, тип элемента и типы атрибутов в классе объектов - это один и тот же список студентов = session.createequery («Select S.Name, c.name от учащегося соединения S.Classes c"). List (); for (iterator item = studies.iterator (); ite.hasnext ();) {object [] obj = (object []) ite.next (); System.out.println (obj [0]); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}
2. Внешнее соединение
Внешние соединения делятся на левое внешнее соединение и справае внешнее подключение. Методы запроса похожи, но результат запроса отличается. Они такие же, как внешнее соединение SQL в результатах запроса. Разница - это метод написания. Конкретный код заключается в следующем:
@Suppresswarnings ({"unchecked", "rawtypes"}) public void testquery () {session session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); // возвращать список атрибутов набора результатов, тип элемента и типы атрибутов в классе объектов - это один и тот же список студентов = session.createequery («select s.name, c.name из левого соединения студента S.classes c"). List (); for (iterator item = studies.iterator (); ite.hasnext ();) {object [] obj = (object []) ite.next (); System.out.println (obj [0]); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}Приведенный выше код использует левый внешний оператор Query. Соответствующий метод запроса правого внешнего соединения аналогичен левому внешнему соединению. Просто конвертируйте налево направо. Данные запроса сохраняются в объекте списка, а содержание запроса можно получить через список.
4. Внешний запрос именования
Внешний именованный запрос относится к написанию операторов запросов в файл отображения и использование тега <Query> для определения операторов HQL в файле отображения. Таким образом, определенные операторы HQL могут реализовать функцию конфигурации функции. Если есть проблема, просто необходимо изменить конфигурацию. Если вы хотите использовать этот оператор SQL, вы можете использовать метод session.getNamedQuery () в программе, чтобы получить строку запроса HQL, как показано в следующем примере.
1. Заявление внешнего запроса
В следующем примере демонстрируется применение операторов внешнего запроса, добавьте тег <Query> в файл отображения, добавьте атрибут имени в тег и добавьте строку в <! [CDATA []]], чтобы соответствующая строка запроса можно было получить в программе в соответствии с атрибутом имени запроса.
<? xml version = "1.0"?> <! Doctype Hibernate Mapping Public "-// Hibernate/Hibernate Mapping Dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <net name/‘com.src.shiberte st.src.shiberte. TABLE = "T_STUDENT"> <ID NAME = "ID"> <Generator // ID> <name = "name"/> <name = "createTime"> </property> <!-Добавьте столбец новых классов к студенту с одной стороны, а имя столбца должно быть таким же, как и список классов. name = "QueryStudent"> <! [CDATA [SELECT S из студента S, где S.ID <? ]]> </Query> </hibernate-mapping>
Внешний именованный запрос помещает оператор запроса в файл отображения, поэтому его можно считать строкой публичного запроса. Это его преимущество, так что другие файлы программы могут быть получены и использованы. Кроме того, это увеличивает удобство модификации как публичной строки.
2. Приложение программы
После определения операторов внешнего запроса необходимо использовать их в программе. HQL предоставляет метод GetNameQuery, чтобы получить строку внешнего оператора запроса. Внешнее имя курсора должно быть добавлено к этому методу. HQL запросит соответствующий блок операторов SQL на основе имени курсора следующим образом:
// Внешний запрос именования @suppresswarnings ({"unchecked", "rawtypes"}) public void testquery () {session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); Список студентов = session.getnamedquery ("QueryStudent"). SetParameter (0, 10) .list (); for (iterator item = studies.ite.hasnext ();) {Студент obj = (студент) ite.next (); System.out.println (obj.getName ()); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}