Prefacio
Los estudiantes que han usado datos de primavera JPA tienen muy claro que todavía es bastante complicado procesar consultas SQL complejas, y la consulta en este artículo se utiliza para simplificar las operaciones de JPA.
QuerydsL define una sintaxis de tipo estático comúnmente utilizado para consultar en datos del modelo de dominio persistente. JDO y JPA son las principales tecnologías de integración de QuerydsL. Este artículo tiene como objetivo explicar cómo usar QuerydsL en combinación con JPA. La consulta de JPA es una alternativa a JPQL y consultas de criterios. QuerydsL es solo un marco general de consultas que se centra en construir consultas SQL seguras de tipo a través de la API Java.
Para usar QueryDSL, se requieren dos operaciones de requisito previo:
1. Agregue dependencias al archivo POM
<
2. Agregue el complemento de compilación al archivo POM
<glugin> <Groupid> com.mysema.maven </proupid> <artifactid> apt-maven-plugin </artifactid> <versión> 1.1.3 </versión> <ecursions> <secution> <setals> <poutso> Process </meta> </metas> <figuration> <utelutdirectory> Target/generado-Sources/java </utendirectorory> <Crocesepor> com.querydsl.apt.jpa.jpaannotationProcessor </cesscesor> </figuration> </secution> </ejecutions> </plugin>
El complemento busca tipos de dominio anotados con Javax.Persistence.Entity y genera los tipos de consulta correspondientes para ellos. La siguiente es la clase de entidad de usuario para ilustrar, y los tipos de consultas generados son los siguientes:
paquete 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 es un tipo de consulta de consulta para el usuario */ @Generated ("com.querydsl.codeGen.EntitySerializer") Public Class Quser extiende EntityPathBase <Ser Usem> {Private estático Long SerialVersionUid = 1153899872l; Public Static Final Quser User = New Quser ("Usuario"); Public Final StringPath Dirección = CreateString ("Dirección"); Número final público Path <Integer> Age = CreateEnumber ("Age", Integer.Class); Número final público Path <Integer> id = createEnumber ("id", integer.class); public Final StringPath Name = CreateString ("Nombre"); public quser (variable de cadena) {super (user.class, forvariable (variable)); } public quser (ruta <? extiende el usuario> ruta) {super (path.gettype (), path.getMetadata ()); } public quser (metadatos de PathMetadata) {super (user.class, metadata); }} Después de haber creado la clase de entidad, ejecute el comando MVN Clean Compli, y será
<OutputDirectory> Target/Generated-Fources/Java </outputDirectory>
Genere el tipo de consulta correspondiente en el directorio. Luego copie todas las clases generadas en el proyecto, solo hágalo.
La entidad involucrada en este artículo es la siguiente:
paquete 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") El usuario de la clase pública implementa serializable { / ** * * / private static final long serialversionUid = 1l; @Id () @GeneratedValue (estrategia = generaciónType.auto) private int id; nombre de cadena privada; dirección de cadena privada; edad privada int; ………… omitir getter, método setter …………/ ** * Atención: * Detalles: Conveniente para ver los resultados de las pruebas * @author chhliu */ @Override public string toString () {return "user [id =" + id + ", name =" + name + ", dirección =" + dirección + ", edad =" + edad + "];"; }}La clase de entidad anterior se usa principalmente para operaciones de una sola tabla.
paquete com.chhliu.springboot.jpa.entity; import javax.persistence.cascadetype; import javax.persistence.entity; import javax.persistence.GeneratedValue; import javax.persistence.id; import javax.persistence.onetoone; import javax.persistence.table; / ** * Descripción: TODO * @Author Chhliu */ @Entity @Table (name = "Person") Persona de clase pública {@ID @GeneratedValue Private Integer ID; nombre de cadena privada; dirección de cadena privada; @Onetoone (mappedby = "persona", cascade = {cascadeType.persist, cascadeType.remove, cascadeType.merge}) privado idcard; ………… omitir getter, método de setter ………… @Override public string toString () {return "persona [id =" + id + ", name =" + name + ", dirección =" + dirección + ", idcard =" + idcard + "]"; }} paquete com.chhliu.springboot.jpa.entity; import 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; / ** * Descripción: * @author chhliu */ @Entity @table (name = "idcard") public class idcard {@id @GeneratedValue Private Integer ID; cadena privada idno; @Onetoone (cascade = {cascadeType.merge, cascadeType.remove, cascadeType.persist}, fetch = fetchType.eager) persona privada persona; ………… omitir getter, método setter ………… @Override public string toString () {return "idcard [id =" + id + ", idno =" + idno + ", persona =" + persona + "]"; }}Las dos entidades anteriores se usan principalmente, por ejemplo, operaciones de relaciones individuales
paquete com.chhliu.springboot.jpa.entity; import java.util.list; import 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; / *** Descripción: Orden Entity Class* @author chhliu*/ @entity @table (name = "orden_c") orden de clase pública {@id @GeneratedValue @column (name = "id") ID de entero privado; @Column (longitud = 20, name = "Order_name") Private String Order Name; @Column (name = "Count") Conteo de enteros privados; @Onetomany (mappedby = "orden", cascade = {cascadeType.persist, cascadeType.remove}, fetch = fetchType.eager) Lista privada <SderItem> OrderItems; ……… omitir getter, método setter ……} paquete com.chhliu.springboot.jpa.entity; import 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.JOIncolumn; import javax.persistence.ManytoOne; import javax.persistence.table; / *** Descripción: OrderItem Entity Class* @author chhliu*/ @Entity @table (name = "Order_item") Public Class OrderItem {@ID @GeneratedValue @column (name = "id", nullable = false) ID de entero privado; @Column (name = "item_name", longitud = 20) String privado String itemName; @Column (name = "precio") Precio privado entero; @ManyToOne (cascade = {cascadeType.persist, cascadeType.remove, cascadeType.merge}, fetch = fetchType.eager) @joincolumn (name = "orden_id") orden de orden privado; ………… omitir getter, método setter ………} Las dos entidades anteriores se usan para mostrar operaciones de ejemplo de una relación de uno a muchos.
Primero, veamos la operación de una sola tabla
1. Use datos de primavera JPA
Para usar la función de consulta proporcionada por Spring Data JPA, es muy simple, solo heredan la interfaz directamente. Spring Data JPA proporciona la interfaz QuerydsLPredicateExecutor, que se utiliza para admitir la interfaz de operación de consulta de consultas, de la siguiente manera:
paquete com.chhliu.springboot.jpa.repository; importar org.springframework.data.jpa.repository.jparepository; importar org.springframework.data.querydsl.querydslPredicateExecutor; import com.chhliu.springboot.jpa.entity.user; Interfaz pública UserRepositoryDLS extiende jParepository <User, Integer>, QuerydsLPredicateExecutor <serer> {// Interfaz de herencia}La interfaz QuerydsLPredicateExecutor proporciona los siguientes métodos:
Interfaz pública QuerydsLPredicateExecutor <t> {t hindone (predicción predicada); Iterable <t> findall (predicada predecir, ordenar); ITerable <T> Findall (predicción predicada, OrderSpecifier <?> ... órdenes); Iterable <t> findall (OrderSpecifier <?> ... órdenes); Página <T> Findall (predicción predicta, concordante daños); recuento largo (predicción predicada); Existe booleano (predicado de predicado); } El uso del método anterior es similar a otros métodos de uso de la interfaz en Spring Data JPA. Para más detalles, consulte: http://www.vevb.com/article/137757.htm
Las pruebas son las siguientes:
El usuario público FindUserByUsername (nombre de usuario final de cadena) { / ** * Este ejemplo es usar Spring Data QuerydsL para implementar * / QUSER QUSER = QUSER.USER; Predicado predicado = quser.name.eq (nombre de usuario); // Según el nombre de usuario, consulta el repositorio de retorno de la tabla de usuario.findone (predicado); }El SQL correspondiente es el siguiente:
La copia del código es la siguiente: seleccione User0_.id como ID1_5_, user0_.address como dirección2_5_, user0_.age como edad3_5_, user0_.name as name4_5_ desde t_user user0_ donde user0_.name =?
El código de ejemplo de operación de la tabla única es el siguiente:
paquete com.chhliu.springboot.jpa.repository; import java.util.list; import javax.persistence.EntityManager; import javax.persistence.persistenceContext; import javax.persistence.query; import javax.transaction.transactional; importar org.springframework.beans.factory.annotation.aUtowired; importar org.springframework.data.domain.pagerequest; importar org.springframework.data.domain.sort; importar 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; / ** * Descripción: Querydsl JPA * @Author Chhliu */ @Component @Transactional Public Class UserRepositoryManagerdsL {@AUTOWIREDREDIRED USERREPRESITORYDLS Repository; @AUtowired @PersistenceContext Private EntityManager EntityManager; Private JPAQueryFactory QUERYFACTORY; @PostConstruct public void init () {queryFactory = new JPAQueryFactory (EntityManager); } Usuario público FindUserByUsername (nombre de usuario de cadena final) { / *** Este ejemplo es usar Spring Data QuerydsL para implementar* / QUSER QUSER = QUSER.USER; Predicción predicto = quser.name.eq (nombre de usuario); return Repository.Findone (predicado); } / *** Atención:* Detalles: consulte todos los registros en la tabla de usuario* / lista pública <serem> findall () {quser quser = quser.user; return queryFactory.SelectFrom (Quser) .fetch (); } / *** Detalles: consulta de condición única* / Usuario público FindonebyUsername (nombre de usuario de cadena final) {QUSER QUSER = QUSER.USER; return QUYFACTORY.SelectFrom (Quser) .Where (Quser.name.eq (UserName)) .Fetchone (); } / *** Detalles: consulta de una sola tabla multi-condición* / Usuario público FindonebyUsernameSeandDdress (nombre de usuario de cadena final, dirección de cadena final) {QUSER QUSER = QUSER.USER; return QUERYFACTORY.Select (QUSER) .FROM (QUSER) // Las dos oraciones anteriores son equivalentes a SelectFrom .Where (QUSER.NAME.EQ (USERNAME). Y (quser.address.eq (direcciones))) // Este código es equivalente a donde (quser.name.eq (username), quser.address.eq (dirección). } / *** Detalles: use la consulta de unión* / lista pública <serem> findusersbyjoin () {quser quser = quser.user; QUSER USERNAME = NUEVO QUSER ("Nombre"); return QUYFACTORY.SelectFrom (QUSER) .innerJoin (QUSER) .on (QUSER.ID.InTValue (). Eq (username.id.intvalue ()) .fetch (); } / ** * Detalles: Ordenar resultados de consulta * / lista pública <serem> finduserAndorder () {quser quser = quser.user; return queryFactory.SelectFrom (Quser) .OrderBy (quser.id.desc ()) .fetch (); } / ** * Detalles: Grupo usando * / Public List <String> FindUserByGroup () {QUSER QUSER = QUSER.USER; return QUERYFACTORY.Select (QUSER.NAME) .FROM (QUSER) .GROUPBY (QUSER.NAME) .FETCH (); } / *** Detalles: Elimine el usuario* / public Long DeleteUser (String UserName) {QUSER QUSER = QUSER.USER; return queryFactory.delete (Quser). Dwhere (Quser.name.eq (UserName)). Execute (); } / *** Detalles: Actualice el registro* / public Long UpdateUser (User User U, Nombre de usuario de cadena final) {QUSER QUSER = QUSER.USER; return QUYFACTORY.Update (QUSER) .Where (quser.name.eq (username)) .set (quser.name, u.getName ()) .set (quser.age, u.getage ()) .set (quser.address, u.getAddress ()) .execute (); } / ** * Detalles: Use consulta nativa * / Public User FindoneUserByOrigInalSql (nombre de usuario final de cadena) {quser quser = quser.user; QUERY QUERY = QUIERYFACTORY.SELECTFROM (QUSER) .Where (Quser.name.eq (UserName)). CreateQuery (); return (user) Query.getSingLeresult (); } / *** Detalles: Consulta de paginación Tabla única* / Página pública <serem> FindAllandPager (Final Int Offset, Final Int PageSize) {predicada predicada = quser.user.id.lt (10); Sort sort = new Sort (new Sort.order (sort.direction.desc, "id")); Pagequest pr = new Pagequest (offset, pageSize, sort); return Repository.Findall (predicado, PR); }}Los ejemplos de operación múltiples (uno a uno) son los siguientes:
paquete com.chhliu.springboot.jpa.repository; import java.util.arrayList; import java.util.list; import javax.annotation.postConstruct; import javax.persistence.EntityManager; import javax.persistence.persistenceContext; importar org.springframework.beans.factory.annotation.aUtowired; importar 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.predicate; 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); } / *** Detalles: consulta dinámica de múltiples table* / lista pública <Tuple> findallPersonAndIdCard () {predicada predicada = (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 (predicarse); return jpaquery.fetch (); } / *** Detalles: la consulta de salida resulta en dto* / pública list <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 (predicarse); List <Tuple> tuples = jpaquery.fetch (); Lista <PustreDCardDTO> DTOS = new ArrayList <PustreDCardDTO> (); if (null! = tuples &&! tuples.isEmpty ()) {for (tuple tuple: tuples) {string dirección = tuple.get (qperson.person.address); Name de cadena = tuple.get (qperson.person.name); Cadena idcard = tuple.get (qidcard.idcard.idno); PersonIdCardDto dto = new PersonIdCardDTO (); dto.setaddress (dirección); dto.setidno (idcard); dto.setName (nombre); dtos.add (dto); }} return dtos; } / *** Detalles: consulta dinámica de múltiples table y paginación* / pública QueryResults <Tuple> findByDtoAndPager (int offset, int pagAgesize) {predicada predicada = (qperson.person.id.intvalue ()). Eq (qidcard.idcard.person.id.intvalue ()); return QUERYFACTORY.Select (qidcard.idcard.idno, qperson.person.address, qperson.person.name) .From (qidcard.idcard, qperson.person) .where (predicate) .Offset (offset) .limit (pageSize) .FetchResults (); }}En el ejemplo anterior donde se producen los resultados de la consulta en modo DTO, después de que se termina la consulta, los resultados de la consulta se convierten manualmente en objetos DTO. Este método en realidad no es muy elegante. Querydsl nos proporciona una mejor manera, vea el siguiente ejemplo:
/ *** Detalles: Método 1: Use la proyección de bean*/ public List <PustreDCardDto> findByDTouseBean () {predicada predicada = (qperson.person.id.intvalue ()). Eq (qidcard.idcard.person.id.intvalue ()); return queryFactory.select (proyectss.bean (personidcarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) .From (qidcard.idcard, qperson.person) .where (predicarse) .fetch (); } / ** * Detalles: Método 2: Use campos en lugar de setter * / public List <PustreDCardDto> findByDTouseFields () {predicate predict = (qperson.person.id.intvalue ()). Eq (qidcard.idcard.person.id.intvalue ()); return QUERYFACTORY.Select (Projections.fields (personidCarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) .From (qidcard.idcard, qperson.person) .where (predicarse) .fetch (); } / *** Detalles: Método 3: Use el método del constructor, tenga en cuenta que el orden de los atributos en el constructor debe ser consistente con el orden en el constructor* / public List <PersonidCarddto> findByDTouseConstructor () {predicada predicto = (qperson.person.id.intvalue (). return QUERYFACTORY.Select (Projections.Constructor (PersonidCarddto.Class, Qperson.person.name, Qperson.person.address, qidcard.idcard.idno)) .From (qidcard.idcard, qperson.person) .where (predicarse) .fetch (); } Lo anterior solo proporciona varias ideas. Por supuesto, también puede usar @QueryProyection para implementarlo, lo cual es muy flexible.
Ejemplo de uno a muchos:
paquete com.chhliu.springboot.jpa.repository; import java.util.list; import javax.annotation.postConstruct; import javax.persistence.EntityManager; import javax.persistence.persistenceContext; importar org.springframework.beans.factory.annotation.aUtowired; importar 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.predicate; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaqueryFactory; @Component Public Class OrderAndOrderItemManager {@aUtowired @PersistenceContext Private EntityManager EntityManager; Private JPAQueryFactory QUERYFACTORY; @PostConstruct public void init () {queryFactory = new JPAQueryFactory (EntityManager); } /*** Detalles: One to-Many, consulta condicional* /Lista pública <Tuple> findOrderAnderInderImbyOrderName (String Order Name) {// Agregar condiciones de consulta predicada = qorder.ordername.eq (OrderName); JPAQuery <Tuple> JPAQuery = QUIERYFACTORY.Select (Qorder.order, qorderitem.orderitem) .From (qorder.order, qorderitem.orderitem) .where (qorderitem.orderitem.order.id.intvalue (). Eq (qorder.order.id.intvalue ()), predicto); // Obtener el resultado return jpaquery.fetch (); } /*** Detalles: consulta de unión de múltiples table* /lista pública <Tuple> findallByOrderName (String Order Name) {// Agregar condiciones de consulta predicada = qorder.ordername.eq (ordenname); JPAQuery <Tuple> JPAQuery = QUIERYFACTORY.SELECT (QODER.ORDER, QODERSEITEM.OrderIm) .From (qorder.order, qorderitem.orderitem) .rrightjoin (qorder.order) .on (qorderitem.orderitem.order.id.intvalue (). Eq (qorder.ord.id.intvalue ())); jpaquery.where (predicado); // Obtener el resultado return jpaquery.fetch (); }} Del ejemplo anterior, podemos ver que QuerydsL ha simplificado enormemente nuestras operaciones
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.