Préface
Les étudiants qui ont utilisé les données de printemps JPA sont très clairs qu'il est encore assez compliqué de traiter des requêtes SQL complexes, et le resertydsl de cet article est utilisé pour simplifier les opérations de JPA.
QueryDSL définit une syntaxe de type statique couramment utilisée pour interroger les données du modèle de domaine persistant. JDO et JPA sont les principales technologies d'intégration de QueryDSL. Cet article vise à expliquer comment utiliser QueryDSL en combinaison avec JPA. Les queryDSL de JPA sont une alternative aux requêtes JPQL et Critères. QueryDSL n'est qu'un cadre de requête général qui se concentre sur la création de requêtes SQL sécurisées de type via l'API Java.
Pour utiliser QueryDSL, deux opérations préalables sont nécessaires:
1. Ajouter des dépendances au fichier POM
<! - Query dsl -> <dependency> <proupId> com.querydsl </proupId> <ArtifActid> querydsl-jpa </ artifactid> </dEpendency> <Dedency> <ProupID> com.querydsl </proped> <estfactid> queryDSL-APT </ artifactid> <tcope> fourni </scope> </Dedency>
2. Ajouter le plug-in de compilation au fichier POM
<harin> <proupId> com.mysema.maven </prôdId> <Artifactid> Apt-Maven-Plugin </Retifactid> <DERSE> 1.1.3 </ Version> <Executions> <Exécution> <Wital> Process </ but> </ buts> <fracilitDirctory> <pteporor> com.querydsl.apt.jpa.jpaannotationprocessor </ptepor> </FIGIFIGURATION> </ EXECUTION> </EMICATIONS> </ Plugin>
Le plugin recherche des types de domaine annotés avec Javax.Persistence.entity et génère des types de requête correspondants pour eux. Ce qui suit est la classe d'entité utilisateur à illustrer, et les types de requête générés sont les suivants:
package com.chhliu.springboot.jpa.entity; import static com.querydsl.core.types.pathmetadatafactory. *; import com.querydsl.core.types.dsl. *; import com.querydsl.core.types.pathmetadata; import javax.annotation.generated; import com.querydsl.core.types.path; / ** * QUSER est un type de requête QueryDSL pour l'utilisateur * / @Generated ("com.Querydsl.codegen.EntitySerializer") Classe publique QUser étend entityPathBase <User> {private static final SerialVersionUID = 1153899872L; public static final QUser utilisateur = new QUser ("utilisateur"); public final StringPath Address = CreateString ("adresse"); public final NumberPath <Integer> Age = Createenumber ("Age", Integer.class); public final NumberPath <Integer> id = createenumber ("id", Integer.class); public final StringPath name = CreateString ("name"); public QUser (variable de chaîne) {super (user.class, forvariable (variable)); } public QUser (path <? étend l'utilisateur> path) {super (path.getType (), path.getMetAdata ()); } public QUser (Pathmetadata Metadata) {super (user.class, métadonnées); }} Après avoir créé le cours d'entité, puis exécuter la commande MVN Clean Compli, et ce sera
<utputDirectory> Target / généré-Sources / Java </utputdirectory>
Générez le type de requête correspondant dans le répertoire. Copiez ensuite toutes les classes générées dans le projet, faites-le.
L'entité impliquée dans cet article est la suivante:
package com.chhliu.springboot.jpa.entity; import 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 utilisateur implémente serializable {/ ** * * / private static final long SerialVersionUID = 1l; @Id () @GeneratedValue (Strategy = GenerationType.Auto) private int id; nom de chaîne privé; adresse de chaîne privée; Âge privé; ………… Omit Getter, méthode du setter ………… / ** * ATTENTION: * Détails: Pratique pour afficher les résultats des tests * @Author Chhliu * / @Override public String toString () {return "User [id =" + id + ", name =" + name + ", adresse =" + adresse + ", âge =" + âge + "]"; }}La classe d'entité ci-dessus est principalement utilisée pour les opérations de table unique.
package com.chhliu.springboot.jpa.entity; Importer javax.persistence.cascaDeType; import javax.persistence.entity; import javax.persistence.generatedValue; import javax.persistence.id; import javax.persistence.onetoone; import javax.persistence.Table; / ** * Description: TODO * @Author Chhliu * / @entity @Table (name = "Person") Public Class Person {@id @GeneratedValue Private Integer ID; nom de chaîne privé; adresse de chaîne privée; @Onetoone (mappedby = "personne", cascade = {CascadeType.persiste, CascadeType.Remove, CascadeType.Merge}) IDCard privé IDCard; ………… Omit Getter, Method Setter ………… @Override public String toString () {return "personne [id =" + id + ", name =" + name + ", adresse =" + adresse + ", idcard =" + idcard + "]"; }} package com.chhliu.springboot.jpa.entity; Importer javax.persistence.cascaDeType; import javax.persistence.entity; import javax.persistence.fetchType; import javax.persistence.generatedValue; import javax.persistence.id; import javax.persistence.onetoone; import javax.persistence.Table; / ** * Description: * @author chhliu * / @entity @table (name = "idcard") public class idcard {@id @generatedvalue private Integer id; chaîne privée idno; @Onetoone (cascade = {Cascadetype.merge, CascadeType.Remove, CascadeType.persiste}, fetch = fetchtype.eager) Personne privée; ………… Omit Getter, Method Setter ………… @Override public String toString () {return "idcard [id =" + id + ", idno =" + idno + ", personne =" + personne + "]"; }}L'entité ci-dessus est principalement utilisée par exemple les opérations de relations un à un
package com.chhliu.springboot.jpa.entity; Importer java.util.list; Importer javax.persistence.cascaDeType; 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; / ** * Description: Order Entity Class * @author chhliu * / @entity @table (name = "ORDER_C") Public Class Order {@id @generatedvalue @column (name = "id") ID entier privé; @Column (longueur = 20, name = "order_name") String privé orderName; @Column (name = "count") Private Integer Count; @Onetomany (mappedBy = "Order", Cascade = {CascadeType.persiste, CascadeType.Remove}, fetch = fetchType.EAGER) Liste privée <C.C.C.C.COMDERITEMS; ……… omettre Getter, méthode du setter ……} package com.chhliu.springboot.jpa.entity; Importer javax.persistence.cascaDeType; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.fetchType; import javax.persistence.generatedValue; import javax.persistence.id; Importer javax.persistence.joinColumn; Importer Javax.Persistence.ManyToOne; import javax.persistence.Table; / ** * Description: Classe de l'entité d'OrderItem * @Author Chhliu * / @entity @Table (name = "ORDER_ITEM") Classe publique OrderItem {@id @generatedValue @Column (name = "id", nullable = false) private Integer id; @Column (name = "item_name", longueur = 20) String privé itemName; @Column (name = "Price") Prix Private entier; @ManyToOne (Cascade = {CascadeType.Persist, CascadeType.Remove, CascadeType.merge}, fetch = fetchType.EAger) @joincumn (name = "ORDER_ID") Ordre Private Order; ………… omettre Getter, méthode du setter ………} L'entité ci-dessus est utilisée pour montrer des exemples de fonctions d'une relation un-à-plusieurs.
Tout d'abord, regardons l'opération de table unique
1. Utilisez les données de printemps JPA
Pour utiliser la fonction QueryDSL fournie par Spring Data JPA, il est très simple, il suffit de hériter directement de l'interface. Spring Data JPA fournit l'interface QueryDSLPredicateExECUTOR, qui est utilisée pour prendre en charge l'interface de fonctionnement QueryDSL Query, comme suit:
package com.chhliu.springboot.jpa.Repository; import org.springframework.data.jpa.repository.jParePository; import org.springframework.data.querydsl.QuerydslPredicateExECUTOR; import com.chhliu.springboot.jpa.entity.user; Interface publique UserRepositoryDLS étend JParePository <utilisateur, entier>, queryDSLPredicateExECUTOR <User> {// Interface d'héritage}L'interface queryDSLPredicateExEcutor fournit les méthodes suivantes:
Interface publique QueryDSLPredicateExEcutor <T> {t FindOne (Predicat Predict); ITable <T> Findall (prédicat prédicat, tri tri); ITable <T> Findall (prédicat prédicat, orderspecificier <?> ... ordres); ITable <T> Findall (Orderspecifier <?> ... ordres); Page <T> FindAll (prédicat prédit, pagable pagable); comptage long (prédicat prédicat); Booléen existe (prédicat prédicat); } L'utilisation de la méthode ci-dessus est similaire aux autres méthodes d'utilisation d'interface dans les données de printemps JPA. Pour plus de détails, veuillez consulter: http://www.vevb.com/article/137757.htm
Les tests sont les suivants:
L'utilisateur public finseUserByUserName (Final String Username) {/ ** * Cet exemple est d'utiliser Spring Data QueryDSL pour implémenter * / Quser QUser = QUser.User; Predicat Predicat = QUser.name.eq (nom d'utilisateur); // Selon le nom d'utilisateur, interrogez la table utilisateur Return Repository.FindOne (Predicat); }Le SQL correspondant est le suivant:
La copie de code est la suivante: Sélectionnez User0_.id en tant qu'ID1_5_, User0_.Address en tant qu'adress2_5_, user0_.age en tant qu'âge3_5_, user0_.name comme name4_5_ à partir de t_user user0_ où user0_.name =?
Le code d'exemple de l'opération de table unique est le suivant:
package com.chhliu.springboot.jpa.Repository; Importer java.util.list; import javax.persistence.entityManager; Importer javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.transaction.transactionnel; 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.predicate; import com.querydsl.jpa.impl.jpaqueryfactory; / ** * Description: querydsl jpa * @author chhliu * / @component @Transactional public class userRepositoryManagerDSL {@autowired private userRepositoryDls Repository; @Autowired @persistenceContext EntityManager EntityManager; JPAQueryFactory Private QueryFactory; @PostConstruct public void init () {queryfactory = new JPaQueryFactory (EntityManager); } Utilisateur public FindUserByUserName (Final String Username) {/ ** * Cet exemple est d'utiliser Spring Data QueryDSL pour implémenter * / Quser QUser = QUser.User; Prédicat prédite = QUser.name.eq (nom d'utilisateur); return Repository.FindOne (Predicat); } / ** * ATTENTION: * Détails: requête tous les enregistrements dans la table utilisateur * / Liste publique <User> findall () {Quser QUser = Quser.user; return queryFactory.SelectFrom (QUser) .Fetch (); } / ** * Détails: requête unique * / utilisateur public findOneByUsername (Nom d'utilisateur final de chaîne) {QUser QUser = Quser.user; return queryfactory.selectFrom (QUser) .Where (QUser.name.eq (nom d'utilisateur)) .Fetchone (); } / ** * Détails: Requête multi-conditions de table unique * / utilisateur public FindOneByUserAmandAdDress (Nom d'utilisateur final de chaîne, adresse de chaîne finale) {Quser QUser = QUser.user; return queryfactory.select (QUser) .from (QUser) // Les deux phrases ci-dessus sont équivalentes à Select .Fetchone (); } / ** * Détails: Utilisez la requête de jointure * / public <utilisateur> finUSERSBYJOIN () {QUser QUser = QUser.User; QUSER Username = new QUser ("Name"); return queryfactory.selectFrom (QUser) .InnerJoin (QUser) .on (QUser.id.intValue (). Eq (username.id.intvalue ())) .fetch (); } / ** * Détails: Triez les résultats de la requête * / Liste publique <User> FindUserAndOrder () {QUser QUser = QUser.User; return queryfactory.selectFrom (QUser) .OrderBy (QUser.id.desc ()) .Fetch (); } / ** * Détails: Groupe à l'aide de * / public List <string> FindUserByGroup () {QUser QUser = QUser.User; return queryfactory.select (QUser.name) .From (QUser) .GroupBy (QUser.Name) .Fetch (); } / ** * Détails: Supprimer l'utilisateur * / public long DeleteUser (String Username) {QUser QUser = QUser.User; return queryfactory.delete (QUser) .Where (QUser.name.eq (nom d'utilisateur)). Execute (); } / ** * Détails: Mettez à jour l'enregistrement * / public Long UpdateUser (Final User U, Final String Username) {QUser QUser = QUser.User; return queryfactory.update (QUser) .Where (QUser.name.eq (nom d'utilisateur)) .set (QUser.Name, U.GetName ()) .Set (QUser.age, U.Getage ()) .set (QUser.Address, U.GetAddress ()) .ExECUTE (); } / ** * Détails: Utilisez la requête native * / utilisateur public FindOneUserByoriginalsQL (Nom d'utilisateur final de chaîne) {QUser QUser = QUser.User; Query Query = queryFactory.SelectFrom (QUser) .Where (QUser.Name.eq (nom d'utilisateur)). CreateQuery (); return (utilisateur) query.getSingleResult (); } / ** * Détails: Pagination Query Table unique * / PAME PUBLIQUE <DERSER> FINDALLANDPAGRER (Final int offset, final int pageSize) {Predicat Predicate = Quser.user.id.lt (10); Sort Sort = new SORT (new Sort.Order (Sort.Direction.desc, "ID")); PageRequest pr = new PageRequest (offset, pagesize, tri); return Repository.Findall (prédicat, pr); }}Les exemples de fonctionnement multiples (un à un) sont les suivants:
package com.chhliu.springboot.jpa.Repository; import java.util.arraylist; Importer java.util.list; import javax.annotation.posstruct; import javax.persistence.entityManager; Importer javax.persistence.PersistenceContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.sterereotype.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.predicate; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaqueryfactory; @Component public class PersonanDIDCardManager {@Autowired @PersisCenContext EntityManager EntityManager; JPAQueryFactory Private QueryFactory; @PostConstruct public void init () {queryfactory = new JPaQueryFactory (EntityManager); } / ** * Détails: Query dynamique multi-table * / Liste publique <Uple> FindAllPersonAndidCard () {Predicat Predicat = (qPerson.person.id.intValue ()). Eq (qidcard.idcard.person.id.intvalue ()); Jpaquery <uple> jpaquery = queryfactory.select (qidcard.idcard.idno, qPerson.person.address, qPerson.person.name). return jpaquery.fetch (); } / ** * Détails: les résultats de la requête de sortie dans le DTO * / Liste publique <PersonIdCarddto> findbydto () {Predicat Predict = (qPerson.person.id.intvalue ()). Eq (qidcard.idcard.person.id.intvalue ()); Jpaquery <uple> jpaquery = queryfactory.select (qidcard.idcard.idno, qPerson.person.address, qPerson.person.name). List <Tuple> tuples = jpaquery.fetch (); List <personIdCarddto> dtos = new ArrayList <personIdCarddto> (); if (null! = tuples &&! tuples.isempty ()) {for (tuple tuple: tuples) {String Address = Tuple.get (qPerson.person.address); String name = tuple.get (qPerson.Sonrson.Name); String idcard = tuple.get (qidcard.idcard.idno); PersonIdCarddto dto = new personIdCarddto (); dto.setAddress (adresse); dto.setidno (idcard); dto.setName (nom); DTOS.ADD (DTO); }} return dtos; } / ** * Détails: Query dynamique multi-table et pagination * / public QueryResults <Uple> findByDtoAndPager (int offset, int pagesize) {Predicat Predicate = (qPerson.person.id.intvalue ()). return queryfactory.select (qidcard.idcard.idno, qPerson.person.address, qPerson.person.name). }}Dans l'exemple ci-dessus où les résultats de la requête sont sortis en mode DTO, une fois la requête terminée, les résultats de la requête sont convertis manuellement en objets DTO. Cette méthode n'est en fait pas très élégante. QueryDSL nous fournit une meilleure façon, voir l'exemple suivant:
/ ** * Détails: Méthode 1: Utilisez la projection de bean * / Liste publique <PersonIdCarddto> findByDtouseBean () {Predicat Predicat = (qPerson.Sonrson.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 (Predicat) .fetch (); } / ** * Détails: Méthode 2: Utilisez des champs au lieu de Setter * / Public List <PersonIdCarddTo> findByDtouseFields () {Predicat Predict = (qPerson.Sonrson.id.intValue ()). return queryfactory.select (projections.fields (personidcarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) .from (qidcard.idcard, qperson.person) .where (Predicat) .fetch (); } / ** * Détails: Méthode 3: Utilisez la méthode du constructeur, notez que l'ordre des attributs dans le constructeur doit être cohérent avec l'ordre dans le constructeur * / Liste publique <PersonIdCarddto> findByDtousConstructor () {Predicat Predict = (qPerson.person.id.IntValue ()). Eq (qidcard.idCard.person. return queryfactory.select (projections.constructor (personidcarddto.class, qperson.person.name, qperson.person.address, qidcard.idcard.idno)) .from (qidcard.idcard, qperson.person) .where (prédicat) .fetch (); } Ce qui précède ne fournit que plusieurs idées. Bien sûr, vous pouvez également utiliser @QueryProjection pour l'implémenter, ce qui est très flexible.
Exemple un à plusieurs:
package com.chhliu.springboot.jpa.Repository; Importer java.util.list; import javax.annotation.posstruct; import javax.persistence.entityManager; Importer javax.persistence.PersistenceContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.sterereotype.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.predicate; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaqueryfactory; @Component public class OrderAndOrderItemManager {@Autowired @PerSistenceContext EntityManager EntityManager; JPAQueryFactory Private QueryFactory; @PostConstruct public void init () {queryfactory = new JPaQueryFactory (EntityManager); } / ** * Détails: One-to-Many, Requête conditionnelle * / LISTE PUBLIQUE <UPLE> FINDORDORDORDEDREDEMBYORDNAME (String OrderName) {// Add Query Conditions Predicat Predicate = QOrder.OrderName.Eq (OrderName); JpaQuery <Tuple> jpaQuery = queryfactory.select (QOrder.order, QOrderItem.OrderItem) .from (QOrder.Order, QOrderItem.OrderItem) .Where (QOrderItem.OrderItem.Order.Ded.IntValue). // obtient le résultat return jpaQuery.fetch (); } / ** * Détails: Recherche de jointure multi-tables * / public List <Uple> findallByOrderName (String OrderName) {// Ajouter des conditions de requête prédicat prédicat = qOrder.Order.OrderName.eq (OrderName); JpaQuery <Tuple> jpaQuery = queryfactory.select (QOrder.order, QOrderItem.OrderItem). jpaquery.where (prédicat); // obtient le résultat return jpaQuery.fetch (); }} D'après l'exemple ci-dessus, nous pouvons voir que QueryDSL a considérablement simplifié nos opérations
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.