Vorwort
Studenten, die Spring Data JPA verwendet haben, sind sehr klar, dass es immer noch sehr kompliziert ist, komplexe SQL -Abfragen zu verarbeiten, und der QueryDSL in diesem Artikel wird verwendet, um die JPA -Operationen zu vereinfachen.
QueryDSL definiert eine häufig verwendete statische Typsyntax für die Abfragung an persistenten Domänenmodelldaten. JDO und JPA sind die Hauptintegrationstechnologien von QueryDSL. Dieser Artikel soll erklären, wie QueryDSL in Kombination mit JPA verwendet wird. JPAs QueryDSL ist eine Alternative zu JPQL- und Kriterienabfragen. QueryDSL ist nur ein allgemeines Abfrage-Framework, das sich auf die Erstellung von SQL-Abfragen von Typen über die Java-API konzentriert.
Um QueryDSL zu verwenden, sind zwei Voraussetzungen erforderlich:
1. Fügen Sie der POM -Datei Abhängigkeiten hinzu
<!-Abfrage DSL-> <De vorstellen> <gruppe> com.querydsl </GroupId> <artifactId> querydsl-jpa </artifactId> </abhängig> <depecled> <gruppe> com.QuerydSL </GroupID> <artifactId> Abfragen> </artifactId> </Scope> </Scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope> </scope
2. Fügen Sie das Compilation-Plug-in in die POM-Datei hinzu
<plugin> <groupId>com.mysema.maven</groupId> <artifactId>apt-maven-plugin</artifactId> <version>1.1.3</version> <executions> <execution> <goals> <goal>process</goal> </goals> <configuration> <outputDirectory>target/generated-sources/java</outputDirectory> <Processor> com.querydsl.apt.jpa.jpaannotationsprozessor </prozessor> </configuration> </execution> </executions> </plugin>
Das Plugin sucht nach Domänentypen, die mit Javax.Persistence.Entity kommentiert werden und entsprechende Abfragearten für sie generiert. Das Folgende ist die zu veranschaulichende Benutzerentitätsklasse, und die generierten Abfragetypen sind wie folgt:
Paket com.chhliu.springboot.jpa.Entity; Importieren statischer com.querydsl.core.types.PathMetadatafactory.*; import com.querydsl.core.types.dsl.*; import com.querydsl.core.types.Pathmetadata; javax.annotation.generated; import com.querydsl.core.types.path; / ** * Quser ist ein QueryDSL -Abfragetyp für Benutzer */ @Generated ("com.querydsl.codegen.EntitySerializer") Public Class Quser erweitert EntityPathbase <Ders <Benutzer> {Private Static Final Long Serialversionuid = 115389872l; public static final quser user = new Quser ("Benutzer"); public Final StringPath Address = CreateString ("Adresse"); öffentliche endgültige ZahlPath <Ganzzahl> Alter = CreateNumber ("Alter", 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 (Variable)); } public Quser (Path <? Erweitert Benutzer> Pfad) {Super (path.gettype (), path.getmetadata ()); } public quser (pathetadata metadata) {super (user.class, metadata); }} Nachdem wir die Entitätsklasse erstellt haben, führen Sie den Befehl MVN Clean Compli aus und wird es sein
<ausgabeverzeichnis> Ziel/generierte Sources/Java </outputDirectory>
Generieren Sie den entsprechenden Abfragetyp im Verzeichnis. Kopieren Sie dann alle generierten Klassen in das Projekt, tun Sie es einfach.
Die an diesem Artikel beteiligte Entität lautet wie folgt:
Paket com.chhliu.springboot.jpa.Entity; importieren java.io.serializable; import Javax.Persistence.Entity; import Javax.Persistence.generatedValue; import Javax.Persistence.generationType; import Javax.Persistence.id; import Javax.Persistence.table; @Entity @Table (name = "t_user") Public Class User implementiert serialisierbare { / ** * * / private statische endgültige long serialversionuid = 1l; @ID () @GeneratedValue (Strategie = GenerationType.auto) Private int id; privater Zeichenfolge Name; private String -Adresse; privates int Alter; ………… Gotter, Setter -Methode auslassen …………/ ** * Achtung: * Details: Bequemes Testen der Testergebnisse * @Author chhliu */ @Override public String toString () {{Benutzer return [id = " + id +", name = " + name +", adress = " + adress +", agal = "Age +"] "; }}Die obige Entitätsklasse wird hauptsächlich für einzelne Tabellenoperationen verwendet.
Paket com.chhliu.springboot.jpa.Entity; Javax.Persistence.cascadetype importieren; import Javax.Persistence.Entity; import Javax.Persistence.generatedValue; import Javax.Persistence.id; import Javax.Persistence.onetoone; import Javax.Persistence.table; / ** * Beschreibung: todo * @author chhliu */ @entity @table (name = "person") public class Person {@id @generatedValue private Integer id; privater Zeichenfolge Name; private String -Adresse; @OnetoOne (mapedby = "person", Cascade = {Cascadetype.Persist, Cascadetype.remove, Cascadetype.merge}) Private idCard idCard; ………… Gotter, Setter -Methode auslassen ………… @Override public String toString () {return "Person [id =" + id + ", name =" + name + ", adress =" + adress + ", idcard =" + idcard + "]"; }} Paket com.chhliu.springboot.jpa.Entity; Javax.Persistence.cascadetype importieren; import Javax.Persistence.Entity; import Javax.Persistence.FetchType; import Javax.Persistence.generatedValue; import Javax.Persistence.id; import Javax.Persistence.onetoone; import Javax.Persistence.table; / ** * Beschreibung: * @author chhliu */ @entity @table (name = "idCard") public class idcard {@ID @GeneratedValue private Integer id; private String idno; @OnetoOne (Cascade = {Cascadetype.merge, Cascadetype.remove, Cascadetype.Persist}, Fetch = FetCetType.eager) private Person Person; ………… Gotter, Setter -Methode auslassen ………… @Override public String toString () {return "idCard [id =" + id + ", idno =" + idno + ", person =" + person + "]"; }}Die beiden oben genannten Einheiten werden hauptsächlich verwendet, beispielsweise Operationen von Eins-zu-Eins-Beziehungen
Paket com.chhliu.springboot.jpa.Entity; importieren java.util.list; Javax.Persistence.cascadetype importieren; import Javax.Persistence.Column; import Javax.Persistence.Entity; import Javax.Persistence.FetchType; import Javax.Persistence.generatedValue; import Javax.Persistence.id; Import Javax.Persistence.onetomany; import Javax.Persistence.table; / *** Beschreibung: Bestellentitätsklasse* @author chhliu*/ @entity @table (name = "order_c") öffentliche Klasse Order {@ID @GeneratedValue @column (name = "id") private Integer id; @Column (Länge = 20, name = "order_name") private String orderName; @Column (name = "count") private Ganzzahl zählen; @Onetomany (mapedby = "order", Cascade = {Cascadetype.Persist, Cascadetype.remove}, Fetch = fetCtType.eager) private list <orderItem> orderItems; ……… Gotter, Setter -Methode auslassen ……} Paket com.chhliu.springboot.jpa.Entity; Javax.Persistence.cascadetype importieren; import Javax.Persistence.Column; import Javax.Persistence.Entity; import Javax.Persistence.FetchType; import Javax.Persistence.generatedValue; import Javax.Persistence.id; Import Javax.Persistence.Joincolumn; import Javax.Persistence.manytoone; import Javax.Persistence.table; / *** Beschreibung: OrderItem Entity Class* @author chhliu*/ @entity @table (name = "order_item") public class orderitem {@id @generatedValue @Column (name = "id", nullable = false) private Integer id; @Column (name = "item_name", Länge = 20) private String itemName; @Column (name = "price") Private Ganzzahlpreis; @ManyToone (Cascade = {Cascadetype.Persist, Cascadetype.remove, Cascadetype.merge}, Fetch = FetCetType.eager) @Joincolumn (name = "order_id") privater Reihenfolge; ………… Gotter, Setter -Methode auslassen ………} Die beiden oben genannten Einheiten werden verwendet, um Beispielvorgänge einer Eins-zu-Viele-Beziehung zu zeigen.
Schauen wir uns zunächst den einzelnen Tischvorgang an
1. Verwenden Sie Spring Data JPA
Um die von Spring Data JPA bereitgestellte QueryDSL -Funktion zu verwenden, ist sie sehr einfach, nur die Schnittstelle direkt erben. Spring Data JPA bietet die Schnittstelle QueryDSLPredicateExecutor, die zur Unterstützung der QueryDSL -Abfrage -Operation -Schnittstelle wie folgt verwendet wird:
Paket com.chhliu.springboot.jpa.repository; import org.springframework.data.jpa.repository.jparepository; import org.springframework.data.querydsl.querydslpredicateEexecutor; import com.chhliu.springboot.jpa.entity.user; Die öffentliche Schnittstelle userRepositorydls erweitert JParepository <Benutzer, Integer>, QueryDSLPredicateEexecutor <Bener> {// Inheritance Interface}Die QueryDSLPredicateEexecutor -Schnittstelle enthält die folgenden Methoden:
public interface queryDSLPredicateEexecutor <t> {t findOne (Prädikatvorhersage); Iterable <t> findAll (Prädikat vorhersagen, sortieren); Iterable <t> findAll (Prädikatvorhersage, Bestellungen <?> ... Bestellungen); Iterable <t> findAll (ordnersPecifier <?> ... Bestellungen); Seite <T> findAll (Prädikat vorhersagen, vorließbar); lange Anzahl (Prädikatvorhersage); Boolesche existiert (Prädikatprädikat); } Die Verwendung der obigen Methode ähnelt anderen Schnittstellenverwendungsmethoden in Federdaten JPA. Weitere Informationen finden Sie unter: http://www.vevb.com/article/137757.htm
Die Tests sind wie folgt:
öffentlicher Benutzer findUserByUserName (endgültiger String -Benutzername) { / ** * Dieses Beispiel soll Spring Data QueryDSL zum Implementieren von * / quser quser = quser.user verwenden; Predicate Predicate = quser.name.eq (Benutzername); // Nach dem Benutzernamen die Benutzertabelle return repository.findone (Prädikat) abfragen; }Die entsprechende SQL lautet wie folgt:
Die Codekopie lautet wie folgt: Wählen Sie user0_.id als id1_5_, user0_.address als addres2_5_, user0_.age als Alter3_5_, user0_.name als name4_5_ aus t_user user0_, wo user0_.name =?
Der Beispiel für ein einzelne Tabellenvorgang ist wie folgt:
Paket com.chhliu.springboot.jpa.repository; importieren java.util.list; import Javax.Persistence.EntityManager; import Javax.Persistence.Persistencontext; import Javax.Persistence.Query; import Javax.transaction.transactional; import org.springframework.beans.factory.annotation.autowired; import org.springframework.data.domain.pageRequest; import org.springframework.data.domain.sort; import org.springframework.steretype.comPonent; import com.chhliu.springboot.jpa.entity.quser; import com.chhliu.springboot.jpa.entity.user; import com.Querydsl.core.types.PREDIATE; import com.querydsl.jpa.impl.jpaqueryfactory; / ** * Beschreibung: QueryDSL JPA * @Author chhliu */ @component @transactional public class userRepositoryManagersl {@autowired private userrepositorydls repository; @Autowired @PersistenContext private EntityManager EntityManager; Private jpaQueryFactory QueryFactory; @Postconstruct public void init () {queryFactory = new JPaQueryFactory (EntityManager); } öffentlicher Benutzer findUserByusername (endgültiger String -Benutzername) { / ** * In diesem Beispiel wird Spring Data QueryDSL verwendet, um * / Quser Quser = quser.user zu implementieren; Prädikat predict = quser.name.eq (Benutzername); return repository.findone (Prädikat); } / *** Achtung:* Details: Abfragen Sie alle Datensätze in der Benutzertabelle* / publiclist <Benetzbuchs> findAll () {quser quser = quser.user; return queryFactory.SelectFrom (Quser) .fetch (); } / *** Details: Single-Condition-Abfrage* / public User findOnebyUnername (endgültiger String-Benutzername) {Quser Quser = quser.user; return queryFactory.SelectFrom (Quser) .where (quser.name.eq (Benutzername)) .fetchone (); } / *** Details: Single Table Multi-Condition-Abfrage* / public User findOnebyusernameAnDaddress (endgültiger String-Benutzername, endgültige String-Adresse) {Quser Quser = quser.user; return queryFactory.Select (Quser) .From (Quser) // Die beiden oben genannten Sätze entsprechen ausgewählt. .-fetchone (); } / *** Details: Verwenden Sie die Join -Abfrage* / publiclist <Benetzbuchs> findUsersByJoin () {Quser Quser = Quser.User; Quser userername = new Quser ("Name"); return queryFactory.Selectfrom (Quser) .innerjoin (Quser) .on (quser.id.intValue (). EQ (userername.id.intValue ()) .fetch (); } / ** * Details: Abfrageergebnisse sortieren * / publiclist <Beus> findUerAndorder () {quser quser = quser.user; return queryFactory.SelectFrom (Quser) .OrderBy (quser.id.desc ()) .fetch (); } / ** * Details: Gruppe mit * / publiclist <string> findUserByGroup () {quser quser = quser.user; return queryFactory.Select (Quser.name) .From (Quser) .GroupBy (Quser.Name) .fetch (); } / *** Details: Löschen Sie den Benutzer* / public Long DeleteUser (String -Benutzername) {Quser Quser = Quser.User; return queryFactory.delete (quser) .where (quser.name.eq (Benutzername)). execute (); } / *** Details: Aktualisieren Sie den Datensatz* / public Long UpdateUser (endgültiger Benutzer u, endgültiger String -Benutzername) {quser quser = quser.user; return queryFactory.Update (Quser) .where (quser.name.eq (Benutzername)) .set (quser.name, u.getName ()) .set (Quser.age, u.getage ()) .set (quser.address, u.getAddress ()) .execute (); } / ** * Details: Verwenden Sie native Abfragen * / public user findOnebyoriginalsql (endgültiger String -Benutzername) {Quser quser = quser.user; Query query = queryFactory.selectFrom (Quser) .where (quser.name.eq (Benutzername)). CreateEquery (); return (user) query.getSingleresult (); } / *** Details: Pagination Query Einzeltabelle* / public Page <Benetzbuchs> findAllandpager (endgültiger int offset, endgültig int pageSize) {Predicate Predicate = quser.user.id.lt (10); Sortieren sort = new sort (new sort.order (sort.direction.desc, "id")); PageRequest PR = neuer pageRequest (Offset, pageSize, sortiert); return repository.findall (Prädikat, PR); }}Multi-Table-Betriebsbeispiele (Eins-zu-Eins) sind wie folgt:
Paket com.chhliu.springboot.jpa.repository; Import Java.util.ArrayList; importieren java.util.list; import Javax.annotation.postconstruct; import Javax.Persistence.EntityManager; import Javax.Persistence.Persistencontext; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.comPonent; import com.chhliu.springboot.jpa.dto.personidcarddto; import com.chhliu.springboot.jpa.entity.qidcard; import com.chhliu.springboot.jpa.entity.qidcard; import com.chhliu.springboot.jpa.entity.qperson; import com.querydsl.core.queryResults; import com.querydsl.core.tuple; import com.Querydsl.core.types.PREDIATE; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaqueryfactory; @Component Public Class PersonandIdCardManager {@autowired @PersistenCeContext Private EntityManager EntityManager; Private jpaQueryFactory QueryFactory; @Postconstruct public void init () {queryFactory = new JPaQueryFactory (EntityManager); } / *** Details: Dynamische Abfrage mit mehreren Tabellen* / publiclist <tuple> findAllpersonandidcard () {Predicate Predicate = (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) .where (Predicate); return jpaQuery.fetch (); } / *** Details: Ausgabeabfrage führt zu dto* / publiclist <personidcarddto> findByDto () {Predicate 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) .where (Predicate); Liste <Tuple> tuple = jpaQuery.fetch (); Liste <Personidcarddto> dtos = new ArrayList <PersonidCarddTo> (); if (null! = tupel &&! String name = tuple.get (qperson.person.name); String idcard = tuple.get (qidcard.idcard.idno); Personidcarddto dto = new personidcarddto (); dto.setAddress (Adresse); dto.setIdno (idCard); DTO.SetName (Name); dtos.add (dto); }} return dtos; } / *** Details: Dynamische Abfrage und Pagination von Multi-Tabellen* / public queryResults <Tuple> findByDtoAndpager (int offset, pageSize) {Predicate Predicate = (qperson.person.id.intvalue ()). EQ (qidcard.idcard.person.Id.Id.Intvalue ()); return queryFactory.select (qidcard.idcard.idno, qperson.person.address, qperson.person.name) .from (qidcard.idcard, qperson.person) .Wo (Prädikat) .Offset (offset) .limit (pagetSize) .FetchResulate (); }}Im obigen Beispiel, in dem die Abfrageergebnisse im DTO -Modus ausgegeben werden, werden nach Abschluss der Abfrage die Abfrageergebnisse manuell in DTO -Objekte umgewandelt. Diese Methode ist eigentlich nicht sehr elegant. QueryDSL bietet uns einen besseren Weg. Sehen Sie sich das folgende Beispiel an:
/ *** Details: Methode 1: Verwenden Sie Bean -Projektion*/ öffentliche Liste <personidcarddto> findByDtouseBean () {Predicate Predicate = (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) .where (Predict) .fetch (); } / ** * Details: Methode 2: Verwenden Sie Felder anstelle von Setter * / publiclist <Personidcarddto> findByDtouseFields () {Predicate predict = (qperson.person.id.intvalue ()). EQ (qidcard.idcard.id.Intvalue ()); return queryFactory.select (projections.fields (personidcarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) .from (qidcard.idcard, qperson.person) .where (predicate) .fetch (); } / *** Details: Methode 3: Verwenden Sie die Konstruktormethode, beachten Sie, dass die Reihenfolge der Attribute im Konstruktor mit der Reihenfolge im Konstruktor übereinstimmen muss return queryFactory.select (projections.constructor (personidcarddto.class, qperson.person.name, qperson.person.address, qidcard.idcard.idno)) .from (qidcard.idcard, qperson.person) .where (pdetrict) .fetch (); } Das obige liefert nur mehrere Ideen. Natürlich können Sie auch @QueryProjection verwenden, um es zu implementieren, was sehr flexibel ist.
Eins-zu-viele-Beispiel:
Paket com.chhliu.springboot.jpa.repository; importieren java.util.list; import Javax.annotation.postconstruct; import Javax.Persistence.EntityManager; import Javax.Persistence.Persistencontext; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.comPonent; import com.chhliu.springboot.jpa.entity.qorder; import com.chhliu.springboot.jpa.entity.qorderItem; import com.querydsl.core.tuple; import com.Querydsl.core.types.PREDIATE; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaqueryfactory; @Component public class orderArdorderItemManager {@autowired @PersistenCeContext Private EntityManager EntityManager; Private jpaQueryFactory QueryFactory; @Postconstruct public void init () {queryFactory = new JPaQueryFactory (EntityManager); } /*** Details: Eins-zu-Viele, bedingte Abfrage* /publiclist <tuple> findOrderArderiTemByOrderName (String OrderName) {// Abfragebedingungen Prädikat hinzufügen Prädikat = qorder.order.Ordername.eq (orderName); JPaQuery <Tuple> jpaQuery = queryFactory.Select (Qorder.Order, QorderItem.orderItem) .From (Qorder.Order, QorderItem.OrderItem) .Wo (QorderItem.OrderItem.Order.Ider.id.IntValue (). EQ (Qorder.order.Intem.Intem.),), Prognoct); // das Ergebnis return jpaQuery.fetch (); } /*** Details: Multi-Table-Join-Abfrage* /publiclist <tuple> findAllByOrderName (String orderName) {// Abfragebedingungen Prädikat hinzufügen Prädikat = qorder.Order.Ordername.eq (OrderName); JPaQuery <Tuple> jpaQuery = queryFactory.Select (Qorder.Order, QorderItem.orderItem) .From (Qorder.Order, QorderItem.OrderItem) .Rightjoin (qorder.Order) .on. jpaQuery.where (Prädikat); // das Ergebnis return jpaQuery.fetch (); }} Aus dem obigen Beispiel können wir sehen, dass QueryDSL unsere Operationen stark vereinfacht hat
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.