Предисловие
Студенты, которые использовали Spring Data JPA, очень ясны, что все еще довольно сложно обрабатывать сложные запросы SQL, и QueryDSL в этой статье используется для упрощения операций JPA.
QueryDSL определяет обычно используемый синтаксис статического типа для запросов на данные модели постоянного домена. JDO и JPA являются основными технологиями интеграции QueryDSL. Эта статья направлена на то, чтобы объяснить, как использовать QueryDsl в сочетании с JPA. QueryDsl JPA является альтернативой запросам JPQL и критериям. QueryDsl-это всего лишь общая структура запроса, которая фокусируется на создании SQL-запросов по созданию SQL-защитников через Java API.
Чтобы использовать QueryDsl, требуются две обязательные операции:
1. Добавьте зависимости в файл POM
<!--query dsl --> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <scope>provided</scope> </dependency>
2. Добавьте плагин компиляции в файл POM
<blicin> <groupid> com.mysema.maven </GroupId> <ratifactid> apt-maven-plugin </artifactid> <sersive> 1.1.3 </version> <cervision> <cessuration> <Голы> <come> Процесс </jogle> </ogle> <ponfiguration> <suptureDirectory> target/Generated-sources/java> </overt> <ponfiguration> <suputDirectory> target/gened-sources/java </outputed> <Costrysor> com.querydsl.apt.jpa.jpaannotationprocessor </processor> </configuration> </выполнение> </выполнения> </плагин>
Плагин ищет типы доменов, аннотированные с javax.persistence.entity и генерирует соответствующие типы запросов для них. Ниже приведен класс пользовательских объектов для иллюстрации, а сгенерированные типы запросов следующие:
пакет com.chhliu.springboot.jpa.entity; Импорт static com.querydsl.core.types.pathmetadatafactory.*; Импорт com.querydsl.core.types.dsl.*; Импорт com.querydsl.core.types.pathmetadata; импортировать javax.annotation.generated; Импорт com.querydsl.core.types.path; / ** * Quser - это тип запроса QueryDSL для пользователя */ @generated ("com.querydsl.codegen.entityserializer") открытый класс Quser Events EntityPathbase <user> {Private Static Final Long SerialversionUid = 1153899872L; Public Static Final Quser user = new Quser («Пользователь»); public final stringpath address = createstring ("адрес"); Public Final NumberPath <Integer> age = createNumber ("age", integer.class); Public Final NumberPath <Integer> id = createNumber ("id", integer.class); public final stringpath name = createstring ("name"); public Quser (String variable) {super (user.class, forvariable (переменная)); } public Quser (path <? Extends User> path) {super (path.getType (), path.getMetadata ()); } public Quser (pathmetadata metadata) {super (user.class, metadata); }} После того, как мы создали класс объектов, затем запустили команду MVN Clean Compli, и это будет
<putdirectory> target/сгенерированные источники/java </outputDirectory>
Создайте соответствующий тип запроса в каталоге. Затем скопируйте все сгенерированные классы в проект, просто сделайте это.
Сущность, участвующая в этой статье, заключается в следующем:
пакет com.chhliu.springboot.jpa.entity; импортировать java.io.serializable; Импорт javax.persistence.entity; Импорт javax.persistence.generatedValue; Импорт javax.persistence.GenerationType; Импорт javax.persistence.id; Импорт javax.persistence.table; @Entity @Table (name = "t_user") открытый класс Пользователь реализует serializable { / ** * * / private static final long serialversionuid = 1l; @Id () @generatedValue (стратегия = GenerationType.Auto) Private INT ID; Приватное название строки; частный строковый адрес; частный int возраст; ………… опустить getter, метод сеттера …………/ ** * Внимание: * Подробности: удобно для просмотра результатов теста * @author chhliu */ @Override public String toString () {return «user =" + id + ", name =" + name + ", address =" + ", age =" + age + "]"; }}Класс объектов выше используется в основном для операций с одной таблицей.
пакет com.chhliu.springboot.jpa.entity; Импорт javax.persistence.cascadetype; Импорт javax.persistence.entity; Импорт javax.persistence.generatedValue; Импорт javax.persistence.id; Импорт javax.persistence.onetoone; Импорт javax.persistence.table; / **! Приватное название строки; частный строковый адрес; @Onetoone (mapedby = "person", cascade = {cascadetype.persist, cascadetype.remove, cascadetype.merge}) private idcard idcard; …………. Опубликайте Getter, метод сеттера ………… }} пакет com.chhliu.springboot.jpa.entity; Импорт javax.persistence.cascadetype; Импорт javax.persistence.entity; Импорт javax.persistence.fetchtype; Импорт javax.persistence.generatedValue; Импорт javax.persistence.id; Импорт javax.persistence.onetoone; Импорт javax.persistence.table; / **! частная строка Idno; @Onetoone (cascade = {cascadetype.merge, cascadetype.remove, cascadetype.persist}, fetch = fetchtype.eage) частное лицо; ………… опустить getter, метод сеттера ………… }}Вышеупомянутые две сущности используются в основном, например, операции отношений один на один
пакет com.chhliu.springboot.jpa.entity; импортировать java.util.list; Импорт javax.persistence.cascadetype; Импорт javax.persistence.column; Импорт javax.persistence.entity; Импорт javax.persistence.fetchtype; Импорт javax.persistence.generatedValue; Импорт javax.persistence.id; Импорт javax.persistence.onetomany; Импорт javax.persistence.table; / **! @Column (длина = 20, name = "order_name") частная строка ordername; @Column (name = "count") частное целое число; @Onetomany (mapedby = "order", cascade = {cascadetype.persist, cascadetype.remove}, fetch = fetchtype.eager) частный список <orderitem> orderitems; ……… опустить Getter, метод сеттера ……} пакет com.chhliu.springboot.jpa.entity; Импорт javax.persistence.cascadetype; Импорт javax.persistence.column; Импорт javax.persistence.entity; Импорт javax.persistence.fetchtype; Импорт javax.persistence.generatedValue; Импорт javax.persistence.id; Импорт javax.persistence.joincolumn; Импорт javax.persistence.manytoone; Импорт javax.persistence.table; / **! @Column (name = "item_name", length = 20) private String itemname; @Column (name = "цена") частная целочисленная цена; @Manytoone (cascade = {cascadetype.persist, cascadetype.remove, cascadetype.merge}, fetch = fetchtype.eager) @joincolumn (name = "order_id") Заказ частного порядка; ………… опустить Getter, метод сеттера ………} Вышеупомянутые две сущности используются, чтобы показать примеры операций отношений с одним ко многим.
Во -первых, давайте посмотрим на операцию на одной таблице
1. Используйте Spring Data JPA
Чтобы использовать функцию QueryDsl, предоставленную Spring Data JPA, она очень просто, просто наследуйте интерфейс напрямую. Spring Data JPA предоставляет интерфейс QueryDslPredicateExeCutor, который используется для поддержки интерфейса операции запроса QueryDSL следующим образом:
пакет com.chhliu.springboot.jpa.repository; Импорт org.springframework.data.jpa.repository.jparePository; Импорт org.springframework.data.querydsl.querydslpredicateexecutor; импорт com.chhliu.springboot.jpa.entity.user; Общедоступный интерфейс userRepositorydls Extends jparePository <user, Integer>, QueryDslPredicateExeCutor <user> {// Интерфейс наследования}Интерфейс QueryDslPredicateExeCutor предоставляет следующие методы:
Общедоступный интерфейс QueryDslpredicateExeCutor <T> {t findone (предикат прогнозирует); Итерабильный <t> findall (предикат прогноз, сортировка сортировки); Итерабильный <t> findall (предикат прогноз, OrdersPecifier <?> ... Orders); Итерабильный <t> findall (OrdersPecifier <?> ... Orders); Page <t> findall (предикат прогнозирует, стабильный стабильный); длинный подсчет (прогноз предиката); логический существует (предикат предикат); } Использование приведенного выше метода аналогично другим методам использования интерфейса в DAGA Spring JPA. Для получения подробной информации, пожалуйста, см.
Тесты следующие:
public User FirstUserByUsername (Final String username) { / ** * Этот пример - использовать Spring Data QueryDsl для реализации * / Quser Quser = QUSER.USER; PREDICECE PREDICACE = QUSER.NAME.EQ (имя пользователя); // Согласно имени пользователя, запросите пользовательский таблицу return Repository.findone (Predicate); }Соответствующий SQL выглядит следующим образом:
Кода кода выглядит следующим образом: выберите user0_.id как id1_5_, user0_.address как адрес 2_5_, user0_.age as age3_5_, user0_.name как name4_5_ из t_user user0_ user0_.name =?
Пример операции «Одно таблица» следующим образом:
пакет com.chhliu.springboot.jpa.repository; импортировать java.util.list; Импорт javax.persistence.entityManager; Импорт javax.persistence.persistencecontext; Импорт javax.persistence.query; Импорт javax.transaction.transactional; Импорт org.springframework.beans.factory.annotation.autowired; импорт org.springframework.data.domain.pagerequest; Импорт org.springframework.data.domain.sort; Импорт org.springframework.steretype.component; импорт com.chhliu.springboot.jpa.entity.quser; импорт com.chhliu.springboot.jpa.entity.user; Импорт com.querydsl.core.types.predicate; Импорт com.querydsl.jpa.impl.jpaqueryfactory; / **! @Autowired @persistencecontext Private EntityManager EntityManager; Частный JPaqueryFactory QueryFactory; @Postconstruct public void init () {QueryFactory = new JPaqueryFactory (EntityManager); } public User FirstUserByUsername (Final String username) { / ** * Этот пример - использовать Spring DataDsl для реализации * / QUSER QUSER = QUSER.USER; Predicate прогнозирует = quser.name.eq (имя пользователя); return Repository.findone (предикат); } / *** Внимание:* Подробности: Запрос всех записей в таблице пользователя* / public list <user> findall () {Quser Quser = Quser.user; return QueryFactory.selectFrom (Quser) .fetch (); } / *** Подробности: запрос на одну кондиционирования* / public user findOneByusername (final String username) {QUSER QUSER = QUSER.USER; return QueryFactory.selectFrom (Quser). Где (quser.name.eq (username)) .fetchone (); } / *** Подробности: отдельная таблица Multi-Condition Query* / public user findOneByUsernameAndDress (окончательная строка, имя пользователя, конечный адрес строки) {Quser Quser = QUSER.USER; return QueryFactory.select (QUSER) .FROM (QUSER) // Приведенные выше два предложения эквивалентны SelectFrom. Где (QUSER.NAME.EQ (Имя пользователя). И (QUSER.Adress.EQ (Адрес))) // Этот код эквивалент (QUSER.NAME.EQ (USERNAME), QUSERSERSTERSE); } / *** Подробности: Используйте Query Query* / public <user> finderssbyjoin () {Quser Quser = Quser.user; Quser username = new Quser ("name"); return QueryFactory.selectFrom (Quser) .innerjoin (quser) .on (quser.id.intvalue (). eq (username.id.intvalue ())) .fetch (); } / ** * Подробности: Результаты запроса сортировки * / public list <user> findUserandorder () {Quser Quser = QUSER.USER; return QueryFactory.selectFrom (Quser) .orderby (quser.id.desc ()) .fetch (); } / ** * Подробности: Группа с помощью * / public list <string> finduserbygroup () {Quser Quser = Quser.user; return QueryFactory.select (quser.name) .from (Quser) .groupby (quser.name) .fetch (); } / *** Подробности: удалить пользователя* / public long deleteUser (String username) {Quser Quser = Quser.user; return QueryFactory.delete (Quser). Где (Quser.name.eq (username)). execute (); } / *** Подробности: Обновите запись* / public long UpdateUser (окончательный пользователь U, Final String username) {Quser Quser = QUSER.USER; return QueryFactory.update (Quser). где (Quser.name.eq (username)) .set (quser.name, u.getName ()) .set (quser.age, u.getage ()) .set (quser.address, u.getaddress ()) .execute (); } / ** * Подробности: Используйте натуральный запрос * / public user findOneSerbyoriginalSql (final String username) {Quser Quser = Quser.user; Query Query = QueryFactory.selectFrom (Quser). Где (Quser.name.eq (username)). CreateQuery (); return (user) Query.getsingleresult (); } / *** Подробности: запрос на страницу «Одиночная таблица»* / public page <user> findallandPager (окончательный смещение int, final int pagesize) {Preficate Predicate = quser.user.id.lt (10); Sort sort = new Sort (new sort.order (sort.direction.desc, "id")); PageRequest pr = новый PageRequest (Offset, PageSize, Sort); return Repository.findall (Predicate, PR); }}Многоточные операционные примеры (один к одному) следующие:
пакет com.chhliu.springboot.jpa.repository; импортировать java.util.arraylist; импортировать java.util.list; импортировать javax.annotation.postconstruct; Импорт javax.persistence.entityManager; Импорт javax.persistence.persistencecontext; Импорт org.springframework.beans.factory.annotation.autowired; Import org.springframework.stereotype.component; импорт com.chhliu.springboot.jpa.dto.personidcarddto; Импорт com.chhliu.springboot.jpa.entity.qidcard; Импорт com.chhliu.springboot.jpa.entity.qidcard; импорт com.chhliu.springboot.jpa.entity.qperson; Импорт com.querydsl.core.queryresults; импорт com.querydsl.core.tuple; Импорт com.querydsl.core.types.predicate; Импорт com.querydsl.jpa.impl.jpaquery; Импорт com.querydsl.jpa.impl.jpaqueryfactory; @Component public class personandidcardmanager {@autowired @persistencecontext Private EntityManager EntityManager; Частный JPaqueryFactory QueryFactory; @Postconstruct public void init () {QueryFactory = new JPaqueryFactory (EntityManager); } / *** Подробности: многоточный динамический запрос* / public list <tuple> findallPersonAndIdcard () {Predicate Predicat = (qperson.person.id.intvalue ()). EQ (QIDCARD.IDCARD.PERSON.ID.INTVALUE ()); Jpaquery <tuple> jpaquery = QueryFactory.select (QIDCARD.IDCARD.IDNO, Qperson.person.address, Qperson.person.name) .from (Qidcard.idcard, Qperson.person). Где (предикат); вернуть jpaquery.fetch (); } / *** Подробности: результаты вывода запроса в DTO* / public List <PersonIdcarddto> findbyDto () {Preficate Predict = (qperson.person.id.intvalue ()). EQ (QIDCARD.IDCARD.PERSON.ID.INTVALUE ()); Jpaquery <tuple> jpaquery = QueryFactory.select (QIDCARD.IDCARD.IDNO, Qperson.person.address, Qperson.person.name) .from (Qidcard.idcard, Qperson.person). Где (предикат); Список <Tuple> couples = jpaquery.fetch (); List <PersonidCarddto> dtos = new ArrayList <personIdCarddto> (); if (null! = cuples &&! couples.isempty ()) {for (tuple tuple: couples) {string address = tuple.get (qperson.person.address); String name = tuple.get (qperson.person.name); String idcard = tuple.get (qidcard.idcard.idno); PersonDcarddto dto = new PersonidCarddto (); dto.setAddress (адрес); dto.setidno (idcard); dto.setname (имя); dtos.add (DTO); }} вернуть DTOS; } / *** Подробности: мультител-динамический запрос и страница* / public QueryResults <Tuple> findbyDtoandPager (int offset, int pagesize) {предикат предикат = (qperson.person.id.intvalue ()). Eq (qidcard.idcard.person.idvalue ()); return QueryFactory.select (QidCard.idcard.idno, qperson.person.address, qperson.person.name) .from (Qidcard.idcard, Qperson.person). Где (предикат) .Offset (Offset) .limit (PageSize) .fetchResults (); }}В приведенном выше примере, где результаты запроса выводятся в режиме DTO, после завершения запроса результаты запроса вручную преобразуются в объекты DTO. Этот метод на самом деле не очень элегантен. QueryDsl предоставляет нам лучший способ, см. Следующий пример:
/ *** Подробности: Метод 1: Использовать проекцию бобов*/ public list <personidcarddto> findbydtousebean () {Predicate Predicat = (qperson.person.id.intvalue ()). EQ (Qidcard.idcard.person.id.intvalue ()); return QueryFactory.select (projections.bean (personidcarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) .from (Qidcard.idcard, Qperson.person) .hese (Predicate) .fetch (); } / ** * Подробности: Метод 2: Используйте поля вместо сеттера * / public list <personidcarddto> findbydtousefields () {Predicate Predict = (qperson.person.id.intvalue ()). EQ (Qidcard.idcard.person.id.intvalue ()); return QueryFactory.select (projections.fields (PersonDcarddto.class, QIDCARD.IDCARD.IDNO, Qperson.person.address, Qperson.person.name)) .from (qidcard.idcard, Qperson.person) .hlow (Predicate) .fetch (); } / *** Подробности: Метод 3: Используйте метод конструктора, обратите внимание, что порядок атрибутов в конструкторе должен соответствовать порядку в конструкторе* / public list <personDcarddto> findbydtouseConstructor () {Preficate Predict = (qperson.person.id.intvalue ()). return QueryFactory.select (projections.constructor (PersonDcarddto.class, Qperson.person.name, Qperson.person.address, Qidcard.idcard.idno)) .from (Qidcard.idcard, Qperson.person). Где (предикат) .fetch (); } Вышеуказанное дает только несколько идей. Конечно, вы также можете использовать @QueryProction для его реализации, что очень гибко.
Пример от одного ко многим:
пакет com.chhliu.springboot.jpa.repository; импортировать java.util.list; импортировать javax.annotation.postconstruct; Импорт javax.persistence.entityManager; Импорт javax.persistence.persistencecontext; Импорт org.springframework.beans.factory.annotation.autowired; Import org.springframework.stereotype.component; Импорт com.chhliu.springboot.jpa.entity.qorder; импорт com.chhliu.springboot.jpa.entity.qorderitem; импорт com.querydsl.core.tuple; Импорт com.querydsl.core.types.predicate; Импорт com.querydsl.jpa.impl.jpaquery; Импорт com.querydsl.jpa.impl.jpaqueryfactory; @Component public class orderandorderitemmanager {@autowired @persistencecontext private entitymanager entitymanager; Частный JPaqueryFactory QueryFactory; @Postconstruct public void init () {QueryFactory = new JPaqueryFactory (EntityManager); } /*** Подробности: один-many, условный запрос* /public list <tuple> findorderandOrderitembyRoderName (строка orderName) {// Добавить условия запроса Predicate = Qorder.ordername.eq (ordername); Jpaquery <tuple> jpaquery = queryfactory.select (Qorder.order, Qorderitem.forditem) .from (Qorder.order, Qorderitem.orderitem). Где (Qorderitem.orderitem.order.id.intvalue (). EQ (Qorder.Order.Intvalue ()), предик); // Получить результат return jpaquery.fetch (); } /*** Подробная информация: многотоколонный Query Query* /public list <tuple> findallbyordername (string ordername) {// добавить условия запроса Predicate Predicate = Qorder.ordername.eq (ordername); Jpaquery <tuple> jpaquery = queryfactory.select (Qorder.order, Qorderitem.orderitem) .from (Qorder.order, Qorderitem.orderitem) .rightjoin (Qorder.order) .on (qorderitem.orderitem.der.id.intvalue (). Eq (qorder.Id.Intval.IntVale.Id.Id.IntValue (). jpaquery.where (предикат); // Получить результат return jpaquery.fetch (); }} Из приведенного выше примера мы видим, что QueryDsl значительно упростил наши операции
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.