Prefácio
Os alunos que usaram o Spring Data JPA estão muito claros que ainda é bastante complicado processar consultas complexas do SQL, e o querydsl neste artigo é usado para simplificar as operações JPA.
O querydsl define uma sintaxe do tipo estático comumente usado para consultar os dados do modelo de domínio persistente. JDO e JPA são as principais tecnologias de integração do querydsl. Este artigo tem como objetivo explicar como usar o querydsl em combinação com o JPA. O querydsl da JPA é uma alternativa às consultas de JPQL e critérios. O querydsl é apenas uma estrutura de consulta geral que se concentra na criação de consultas SQL seguras de tipo através da API Java.
Para usar o querydsl, são necessárias duas operações de pré -requisito:
1. Adicione dependências ao arquivo POM
<!-consulta dsl-> <pendency> <puperid> com.Querydsl </groupId> <TRARFACTID> querydsl-jpa </starifactId> </dependency> <pendency> <purince> COM.QUERYDSL </Groupid> <TifactId> querydsl -pt </stifactid> <COPED> </GroupId> <sCope> <sCope> fornecido </scoping> Avensionado
2. Adicione o plug-in de compilação ao arquivo POM
<Plugin> <puperid> com.mysema.maven </frupidId> <stifactId> apt-maven-plugin </artifactId> <versão> 1.1.3 </sipers> <correncions> <aturtDirectory> <gestes> <gale> Process </Goal> </jeal> <figuration> <Act aputerectory> TARGETORY> <GERATENUREST-SURADOR-STOTE/GERATORES-SOBTOLE/GERATERESTR/GERATERESTROMENTE/GERATERESTO/GERATERESTO/GERATERESTO/GERATERESTO/GERATERESTO/GERATERESTE/ <Processor> com.querydsl.apt.jpa.jpaannotationProcessor </socessor> </figuration> </secution> </conformions> </flugin>
O plug -in procura os tipos de domínio anotados com javax.persistence.entity e gera tipos de consulta correspondentes para eles. A seguir, a classe de entidade do usuário para ilustrar, e os tipos de consulta gerados são os seguintes:
pacote com.chhliu.springboot.jpa.entity; importar estático com.Querydsl.core.types.pathmetadatafactory.*; importar com.querydsl.core.types.dsl.*; importar com.querydsl.core.types.pathmetadata; importar javax.annotation.Generated; importar com.querydsl.core.types.path; / ** * QUSER é do tipo querydsl de consulta para usuário */ @Generated ("com.querydsl.codegen.entitySerializer") classe pública QUSER estende entitypathbase <suser> {private static final long serialversionUid = 115389872l; public static final Quser User = new Quser ("Usuário"); public final StringPath endereço = createString ("endereço"); public NumberPath <Integer> Age = CreateNumber ("Age", Integer.class); public NumberPath <Integer> id = createNumber ("id", integer.class); public final StringPath Name = CreateString ("Nome"); public Quser (String variável) {super (user.class, forvariable (variável)); } public quser (path <? estende o usuário> path) {super (path.gettype (), path.getMetadata ()); } public Quser (PathMetadata Metadata) {super (user.class, metadados); }} Depois de criarmos a classe de entidade, execute o comando MVN Clean Compli, e será
<putputDirectory> Target/gerado fonte/java </itputDirectory>
Gere o tipo de consulta correspondente no diretório. Em seguida, copie todas as classes geradas para o projeto, basta fazê -lo.
A entidade envolvida neste artigo é a seguinte:
pacote com.chhliu.springboot.jpa.entity; importar java.io.serializable; importar javax.persistence.Entity; importar javax.persistence.GeneratedValue; importar javax.persistence.generationType; importar javax.persistence.id; importar javax.persistence.table; @Entity @Table (name = "t_user") classe pública o usuário implementa serializável { / ** * * / private estático final serialversionuid = 1L; @Id () @generatedValue (estratégia = generationType.auto) private int id; nome de string privado; endereço de string privado; private Int Age; ………… omita getter, método setter …………/ ** * Atenção: * Detalhes: conveniente para visualizar os resultados do teste * @author chhliu */ @Override public string tostring () {return "user [id =" + id + ", name =" + name + ", endereço =" + ", idade =" " +" + ""; }}A classe de entidade acima é usada principalmente para operações de tabela única.
pacote com.chhliu.springboot.jpa.entity; importar javax.persistence.CASCADETYPE; importar javax.persistence.Entity; importar javax.persistence.GeneratedValue; importar javax.persistence.id; importar javax.persistence.onetoOne; importar javax.persistence.table; / ** * Descrição: TODO * @Author Chhliu */ @Entity @Table (name = "Person") nome de string privado; endereço de string privado; @Onetoone (mapedby = "pessoa", cascade = {cascadeType.persist, cascadetype.remove, cascadetype.merge}) private idcard idcard; ………… omita getter, método setter ………… @Override public string tostring () {return perest [id = " + id +", name = " + name +", endereço = " + endereço +", idcard = " + idcard +"] "; }} pacote com.chhliu.springboot.jpa.entity; importar javax.persistence.CASCADETYPE; importar javax.persistence.Entity; importar javax.persistence.FetchType; importar javax.persistence.GeneratedValue; importar javax.persistence.id; importar javax.persistence.onetoOne; importar javax.persistence.table; / ** * Descrição: * @author chhliu */ @entity @table (name = "idcard") public class Idcard {@id @generatedValue ID inteiro privado; String privada idno; @Onetoone (cascade = {cascadetype.merge, cascadetype.remove, cascadetype.persist}, fetch = fetchtype.ager) pessoa privada; ………… omita getter, método setter ………… @Override public string tostring () {return }}A entidade acima é usada principalmente, por exemplo, operações de relacionamentos individuais
pacote com.chhliu.springboot.jpa.entity; importar java.util.list; importar javax.persistence.CASCADETYPE; importar javax.persistence.column; importar javax.persistence.Entity; importar javax.persistence.FetchType; importar javax.persistence.GeneratedValue; importar javax.persistence.id; importar javax.persistence.onetomany; importar javax.persistence.table; / *** Descrição: Classe de entidade do pedido* @author chhliu*/ @entity @table (name = "order_c") public class Order {@id @generatedValue @column (name = "id") private ID ID inteiro; @Column (length = 20, name = "order_name") private string ordername; @Column (name = "count") contagem inteira privada; @Onetomany (mapedby = "order", cascade = {cascadeType.persist, cascadeType.remove}, fetch = fetchtype.ager) lista privada <landiMiTem> orderItems; ……… omita getter, método setter ……} pacote com.chhliu.springboot.jpa.entity; importar javax.persistence.CASCADETYPE; importar javax.persistence.column; importar javax.persistence.Entity; importar javax.persistence.FetchType; importar javax.persistence.GeneratedValue; importar javax.persistence.id; importar javax.persistence.joincolumn; importar javax.persistence.ManytoOne; importar javax.persistence.table; / *** Descrição: Classe de entidade OrderItem* @author chhliu*/ @entity @table (name = "order_item") public class OrderItem {@id @generatedValue @column (name = "id", anulable = false) private ID; @Column (name = "item_name", comprimento = 20) private string itemName; @Column (name = "price") Preço inteiro privado; @ManytoOne (cascade = {cascadeType.persist, cascadeType.remove, cascadetype.merge}, fetch = fetchtype.eager) @joincolumn (name = "order_id") ordem privada ordem; ………… omita getter, Método Setter ………} A entidade acima é usada para mostrar operações de exemplo de um relacionamento um para muitos.
Primeiro, vejamos a operação de tabela única
1. Use Spring Data JPA
Para usar a função querydsl fornecida pelo Spring Data JPA, é muito simples, apenas herde a interface diretamente. O Spring Data JPA fornece a interface querydslPredicateExector, que é usada para oferecer suporte à interface de operação de consulta Querydsl, como segue:
pacote com.chhliu.springboot.jpa.repository; importar org.springframework.data.jpa.repository.jparepository; importar org.springframework.data.querydsl.querydslPredicateExecutor; importar com.chhliu.springboot.jpa.entity.user; interface pública userRepositoryDls estende JParepository <usuário, número inteiro>, querydslPredicateExecutor <suser> {// interface de herança}A interface querydslPredicateExector fornece os seguintes métodos:
interface pública querydslPredicateExecutor <T> {t foundOne (predicado prediz); Iterable <T> findAll (predicado prevendo, classificar); Iterable <t> findAll (predicado prevendo, pedidos de pedidos <?> ... pedidos); Iterable <t> findAll (pedidos de pedidos <?> ... pedidos); Página <t> findAll (predicado prevendo, pagável pagável); contagem longa (predicado prevendo); existe booleano (predicado predicado); } O uso do método acima é semelhante a outros métodos de uso de interface no JPA de dados da primavera. Para detalhes, consulte: http://www.vevb.com/article/137757.htm
Os testes são os seguintes:
Public User FindUserByUserName (Nome de usuário da String final) { / ** * Este exemplo é usar o Spring Data Querydsl para implementar * / QUSER QUSER = QUSER.USER; Predicado predicado = quser.name.eq (nome de usuário); // De acordo com o nome de usuário, consulte a tabela de usuários repositório.findone (predicado); }O SQL correspondente é o seguinte:
A cópia do código é a seguinte: Selecione User0_.id como id1_5_, user0_.address como endereço2_5_, user0_.age como idade3_5_, user0_.name como name4_5_ de t_user user0_ where user0_.name =?
O código de exemplo de operação de tabela única é a seguinte:
pacote com.chhliu.springboot.jpa.repository; importar java.util.list; importar javax.persistence.EntityManager; importar javax.persistence.persistencecontext; importar javax.persistence.Query; importar javax.Transaction.Transaction; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.data.domain.pagerequest; importar org.springframework.data.domain.sort; importar org.springframework.steretype.component; importar com.chhliu.springboot.jpa.entity.quser; importar com.chhliu.springboot.jpa.entity.user; importar com.querydsl.core.types.predicate; import com.Querydsl.jpa.impl.jpaQueryFactory; / ** * Descrição: Querydsl jpa * @author chhliu */ @component @transaction public class UserRepositoryManagerdsl {@aUTowired private UserRepositoryDls Repositório; @AUTOWIRED @PERSISTENCECONTEXT PRIVATIVENGERMANAGER EntityManager; consulta privada de factorização; @PostConstruct public void init () {QueryFactory = new JPaQueryFactory (entityManager); } Usuário público findUserByUserName (Nome de usuário da String final) { / *** Este exemplo é usar o Spring Data Querydsl para implementar* / quser QUSER = QUSER.USER; Predicado previsto = quser.name.eq (nome de usuário); repositório de retorno.findone (predicado); } / *** Atenção:* Detalhes: Consulte todos os registros na tabela de usuários* / list public <suser> findall () {QUSER QUSER = QUSER.USER; retornar queryfactory.SelectFrom (QUSER) .Fetch (); } / *** Detalhes: consulta de condição única* / usuário público findOneByUserName (Nome de usuário da String final) {QUSER QUSER = QUSER.USER; Return queryFactory.SelectFrom (QUSER). Onde (QUSER.NAME.EQ (nome de usuário)) .FetchOne (); } / *** Detalhes: Consulta de várias condições de tabela única* / Usuário público FindOneByUserNamendDeddress (Nome de usuário da String final, endereço da sequência final) {QUSER QUSER = QUSER.USER; Return queryFactory.Select (quser) .From (quser) // As duas frases acima são equivalentes a selecionar. } / *** Detalhes: Use a consulta de junção* / public list <suser> findUsersByJoin () {QUSER QUSER = QUSER.USER; Nome de usuário QUSER = new Quser ("Nome"); retornar queryFactory.SelectFrom (QUSER) .innerjoin (QUSER) .on (QUSER.id.IntValue (). Eq (UserName.id.IntValue ()) .Fetch (); } / ** * Detalhes: Classifique os resultados da consulta * / public list <suser> findUserrandorder () {QUSER QUSER = QUSER.USER; Return queryfactory.SelectFrom (QUSER) .Orderby (QUSER.id.Desc ()) .Fetch (); } / ** * Detalhes: Grupo usando * / public list <tring> findUserByGroup () {quser QUSER = QUSER.USER; Return queryFactory.Select (QUSER.NAME) .From (QUSER) .Groupby (QUSER.NAME) .FETCH (); } / *** Detalhes: Exclua o usuário* / public Long DeleteUser (Nome de usuário da String) {QUSER QUSER = QUSER.USER; retornar queryfactory.delete (quser) .where (quser.name.eq (nome de usuário)). Execute (); } / *** Detalhes: Atualize o registro* / public Long UpdateUser (Usuário final U, Nome de usuário da String final) {QUSER QUSER = QUSER.USER; Return QueryFactory.Update (QUSER). Onde (QUSER.NAME.EQ (Nome de usuário)) .set (QUSER.NAME, U.GetName ()) .set (QUSER.AGE, U.Getage (). } / ** * Detalhes: Use a consulta nativa * / usuário público findOneUserByorigNalsQL (Nome de usuário da String final) {QUSER QUSER = QUSER.USER; Query Query = QueryFactory.SelectFrom (QUSER). Onde (QUSER.NAME.EQ (Nome de usuário)). Createequery (); return (usuário) query.getSingleResult (); } / *** Detalhes: Consulta de paginação Tabela única* / Public Page <suser> FindalLandPager (Final Int Offset, Final Int PageSize) {predicado predicado = quser.user.id.lt (10); Classificação de classificação = nova classificação (new Sort.Order (Sort.Direction.Desc, "ID")); Pagerequest pr = new pageRequest (deslocamento, PageSize, classificação); repositório de retorno.findall (predicado, pr); }}Exemplos de operação com várias mesa (um para um) são os seguintes:
pacote com.chhliu.springboot.jpa.repository; importar java.util.arraylist; importar java.util.list; importar javax.annotation.postconstruct; importar javax.persistence.EntityManager; importar javax.persistence.persistencecontext; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.tereotype.component; importar com.chhliu.springboot.jpa.dto.personidcarddto; importar com.chhliu.springboot.jpa.entity.qidcard; importar com.chhliu.springboot.jpa.entity.qidcard; importar com.chhliu.springboot.jpa.entity.qperson; importação com.Querydsl.core.QueryResults; importar com.querydsl.core.tuple; importar com.querydsl.core.types.predicate; importar com.Querydsl.jpa.impl.jpaQuery; import com.Querydsl.jpa.impl.jpaQueryFactory; @Component public class PessoandidCardManager {@AUTOWIRED @PERSISTENCECONTEXT EntityManager EntityManager; consulta privada de factorização; @PostConstruct public void init () {QueryFactory = new JPaQueryFactory (entityManager); } / *** Detalhes: consulta dinâmica de várias mesas* / lista pública <Tuple> findAllPersoNAndidCard () {predicado predicado = (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). return jpaquery.fetch (); } / *** Detalhes: Consulta de saída resulta em dto* / list public <SOSOSEDCARDDDO> findBydTo () {predicado previsto = (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). Lista <Tuple> tuplas = jpaQuery.Fetch (); Lista <SOSOSEDCARDDDO> DTOS = new ArrayList <PessoidCarddto> (); if (null! = tuply &&! tuplas.isEmpty ()) {for (tupla tupla: tuply) {string endereço = tuple.get (qperson.person.address); Nome da string = tuple.get (qperson.person.name); String idcard = tuple.get (qidcard.idcard.idno); PersonIdCardDTO DTO = new PersonIdCarddto (); dto.setAddress (endereço); dto.setIdno (IDCARD); dto.setName (nome); dtos.add (DTO); }} retornar dTOs; } / *** Detalhes: Consulta e paginação dinâmica multi-tabela* / Public QueryResults <Tuple> findBydtoandPager (Int Offset, int PageSize) {predicado predicado = (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) .where (predicado) .offset (offset) .limit (Pagesize) .FetchRess (); }}No exemplo acima, onde os resultados da consulta são emitidos no modo DTO, após o término da consulta, os resultados da consulta são convertidos manualmente em objetos DTO. Este método não é realmente muito elegante. Querydsl nos fornece uma maneira melhor, veja o exemplo a seguir:
/ *** Detalhes: Método 1: Use a projeção do feijão*/ Lista pública <SOSOSEDCARDDDO> findBydTouseBean () {predicado predicado = (qperson.person.id.intvalue ()). Eq (qidcard.idcard.person.id.intValue ()); Return QueryFactory.Select (projections.bean (PEROSONIDCARDDTO.CLASS, QIDCARD.IDCARD.IDNO, QPERSON.PERSON.ADDRESS, QPERSON.PERSON.NAME)) .From (Qidcard.idcard, qperson.person). } / ** * Detalhes: Método 2: Use campos em vez de setter * / list public <SOSOSEDCARDDDO> findBydTouseFields () {predicado previc = (qperson.person.id.intvalue ()). Eq (Qidcard.idcard.person.id.IntValue ()); Return QueryFactory.Select (projection.fields (PersonidCarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) .From (Qidcard.idcard, qperson.person). } / *** Detalhes: Método 3: Use o método do construtor, observe que a ordem dos atributos no construtor deve ser consistente com a ordem no construtor* / list public <SOSOSODCARDDDO> findBydTouSeconstructor () {predicado previct = (qperson.person.id.Intvalue ()). Return QueryFactory.Select (projection.Constructor (PersonidCarddto.class, QPERSON.PERSON.NAME, QPERSON.PERSON.Address, Qidcard.idcard.idno)) .From (Qidcard.idcard, qperson.person). } O exposto acima fornece apenas várias idéias. Obviamente, você também pode usar o @QueryProjection para implementá -lo, o que é muito flexível.
Exemplo um para muitos:
pacote com.chhliu.springboot.jpa.repository; importar java.util.list; importar javax.annotation.postconstruct; importar javax.persistence.EntityManager; importar javax.persistence.persistencecontext; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.tereotype.component; importar com.chhliu.springboot.jpa.entity.qorder; importar com.chhliu.springboot.jpa.entity.qorderItem; importar com.querydsl.core.tuple; importar com.querydsl.core.types.predicate; importar com.Querydsl.jpa.impl.jpaQuery; import com.Querydsl.jpa.impl.jpaQueryFactory; @Component public class OrderArDorderItemManager {@AUTOWIRED @PERSISTENCECONTEXT EntityManager EntityManager; consulta privada de factorização; @PostConstruct public void init () {QueryFactory = new JPaQueryFactory (entityManager); } /*** Detalhes: Consulta condicional de um para muitos,* /list public <Tuple> FindErderArderItEMByOrderName (String orderName) {// Adicione condições de consulta predicada predicada = qorder.order.ordername.eq (orderName); JPaQuery <Tuple> jpaQuery = QueryFactory.Select (qorder.order, qorderitem.ordetem) .From (QOrder.Order, qorderItem.OrderItem) .where (qorderItem.OrmItem.Order.Id.IntValue (). Eq (QOORD.Order.Id.IntV ()), Predict.IntValue (). Eq (QOORD.IDER.ID.INT.TALUE (),), Predit.IntValue (). // Obtenha o resultado retornar jpaquery.fetch (); } /*** Detalhes: consulta de junção de várias tabela* /Lista pública <Tuple> findAllByorderName (string orderName) {// Adicione Condições de consulta predicada predicada = qorder.order.orderName.eq (ordername); Jpaquery <Tuple> jpaQuery = QueryFactory.Select (qorder.orde, qorderitem.orderitem) .From (QOrder.Order, qorderItem.OrderItem) .rightJoin (qorder.Order) .OnMid (Qorderitem.OrderM.Order.id.IntValue (). Eq (QOrder). jpaquery.where (predicado); // Obtenha o resultado retornar jpaquery.fetch (); }} A partir do exemplo acima, podemos ver que o querydsl simplificou bastante nossas operações
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.