머리말
Spring Data JPA를 사용한 학생들은 복잡한 SQL 쿼리를 처리하는 것이 여전히 복잡하다는 것이 매우 분명하며,이 기사의 querydsl은 JPA 작업을 단순화하는 데 사용됩니다.
QueryDsl은 영구 도메인 모델 데이터에 대한 쿼리에 일반적으로 사용되는 정적 유형 구문을 정의합니다. JDO와 JPA는 QueryDSL의 주요 통합 기술입니다. 이 기사는 JPA와 함께 querydsl을 사용하는 방법을 설명하는 것을 목표로합니다. JPA의 querydsl은 JPQL 및 기준 쿼리의 대안입니다. QueryDsl은 Java API를 통해 유형-안전 SQL 쿼리를 구축하는 데 중점을 둔 일반적인 쿼리 프레임 워크입니다.
QueryDsl을 사용하려면 두 개의 전제 조건 작업이 필요합니다.
1. POM 파일에 종속성을 추가하십시오
<!-쿼리 dsl-> <pectionency> <groupid> com.querydsl </groupid> <artifactid> querydsl-jpa </artifactid> </dependency> <groupide> com.querydsl </groupid> <artifactid> querydsl-apt> </scope> 제공> </scope> </scope>.
2. 컴파일 플러그인을 POM 파일에 추가하십시오
<Plugin> <groupId> com.mysema.maven </groupId> <artifactid> apt-maven-plugin </artifactid> <bersion> 1.1.3 </version> <executions> <executions> <goving> <govet> 프로세스 </goving> </Goals> <outputDirectory/java/java </outpeppeations-sources/java> <processor> com.querydsl.apt.jpa.jpaannotationprocessor </processor> </configuration> </execution> </executions> </plugin>
플러그인은 javax.persistence.entity로 주석이 달린 도메인 유형을 찾고 해당 쿼리 유형을 생성합니다. 다음은 설명 할 사용자 엔티티 클래스이며 생성 된 쿼리 유형은 다음과 같습니다.
패키지 com.chhliu.springboot.jpa.entity; static com.querydsl.core.types.pathmetadatafactory를 가져옵니다.*; import com.querydsl.core.types.dsl.*; import com.querydsl.core.types.pathmetadata; import javax.annotation.ceenderated; import com.querydsl.core.types.path; / ** * Quser는 사용자 */ @generated ( "com.querydsl.codegen.entitySerializer")를위한 querydsl 쿼리 유형입니다. public class Quser는 EntityPathbase <user> {private static final long serialversionUID = 115389872L; 공개 정적 최종 Quser user = new Quser ( "사용자"); 공개 최종 StringPath 주소 = Createstring ( "주소"); 공개 최종 번호 경로 <integer> age = createNumber ( "Age", Integer.class); 공개 최종 번호 경로 <integer> id = createNumber ( "id", integer.class); public final stringpath name = createString ( "name"); public Quser (String ariable) {super (user.class, forvariable (변수)); } public quser (path <? extrends user> path) {super (path.gettype (), path.getmetadata ()); } public quser (pathmetadata metadata) {super (user.class, metadata); }} 엔티티 클래스를 만든 후 MVN Clean Compli 명령을 실행하면
<outputDirectory> 대상/생성 소스/Java </outputDirectory>
디렉토리에서 해당 쿼리 유형을 생성합니다. 그런 다음 생성 된 모든 클래스를 프로젝트에 복사하고 그냥하십시오.
이 기사에 관련된 엔티티는 다음과 같습니다.
패키지 com.chhliu.springboot.jpa.entity; java.io.serializable import; javax.persistence.entity import; import javax.persistence.generatedValue; import javax.persistence.generationType; javax.persistence.id import; javax.persistence.table import; @entity @table (name = "t_user") 공개 클래스 사용자는 시리얼이 가능성 { / ** * * / private static final long serialversionuid = 1l; @id () @generatedValue (전략 = GenerationType.Auto) private int id; 개인 문자열 이름; 개인 문자열 주소; 사적인 int 연령; ………… getter, setter 방법을 생략 …………/ ** *주의 : * 세부 사항 : 테스트 결과를보기 편리합니다 * @author chhliu */ @override public String () {return "user [id =" + id + ", name =" + name + ", address =" + address + ", age =" + age + "]; }}위의 엔티티 클래스는 주로 단일 테이블 작업에 사용됩니다.
패키지 com.chhliu.springboot.jpa.entity; import javax.persistence.cascadetype; javax.persistence.entity import; import javax.persistence.generatedValue; javax.persistence.id import; import javax.persistence.onetoone; javax.persistence.table import; / ** * 설명 : todo * @author chhliu */ @entity @table (name = "person") 공개 클래스 사람 {@id @generatedvalue 개인 정수 ID; 개인 문자열 이름; 개인 문자열 주소; @onetoone (mappedby = "person", cascade = {cascadetype.persist, cascadetype.remove, cascadetype.merge}) private idcard idcard; ………… getter, setter method를 생략 ………… @override public string tostring () {return "person [id =" + id + ", name =" + name + ", address =" + address + ", idcard =" + idcard + "]; }} 패키지 com.chhliu.springboot.jpa.entity; import javax.persistence.cascadetype; javax.persistence.entity import; import javax.persistence.fetchtype; import javax.persistence.generatedValue; javax.persistence.id import; import javax.persistence.onetoone; javax.persistence.table import; / ** * 설명 : * @author chhliu */ @entity @table (name = "idcard") public class idcard {@id @generatedValue 개인 정수 ID; 개인 문자열 idno; @onetoone (cascade = {cascadetype.merge, cascadetype.remove, cascadetype.persist}, fetch = fetchtype.eger) 개인 사람; ………… getter, setter 메소드를 생략합니다 ………… @override public String tostring () {return "idcard [id =" + id + ", idno =" + idno + ", person =" + person + "]; }}위의 두 엔티티는 주로 일대일 관계의 운영에 사용됩니다.
패키지 com.chhliu.springboot.jpa.entity; Java.util.list 가져 오기; import javax.persistence.cascadetype; javax.persistence.column import; javax.persistence.entity import; import javax.persistence.fetchtype; import javax.persistence.generatedValue; javax.persistence.id import; import javax.persistence.onetomany; javax.persistence.table import; / *** 설명 : 주문 엔티티 클래스* @Author chhliu*/ @entity @table (name = "order_c") 공개 클래스 주문 {@id @generatedValue @Column (name = "id") 개인 정수 ID; @column (길이 = 20, 이름 = "order_name") private String ordername; @Column (이름 = "count") 개인 정수 수; @onetomany (mappedby = "order", cascade = {cascadetype.persist, cascadetype.remove}, fetch = fetchtype.eger) private list <orderitem> orderitems; ……… getter를 생략, 세터 방법 ……} 패키지 com.chhliu.springboot.jpa.entity; import javax.persistence.cascadetype; javax.persistence.column import; javax.persistence.entity import; import javax.persistence.fetchtype; import javax.persistence.generatedValue; javax.persistence.id import; javax.persistence.joincolumn; import javax.persistence.manytoone; javax.persistence.table import; / *** 설명 : OrderItem Entity Class* @Author chhliu*/ @entity @table (name = "order_item") public class orderitem {@id @generatedvalue @column (name = "id", nullable = false) 개인 정수 ID; @column (이름 = "item_name", 길이 = 20) 개인 문자열 itemname; @Column (이름 = "가격") 개인 정수 가격; @manytoone (cascade = {cascadetype.persist, cascadetype.remove, cascadetype.merge}, fetch = fetchtype.eger) @joincolumn (name = "order_id") 개인 주문 순서; ………… getter를 생략, 세터 방법 ………} 위의 두 엔티티는 일대일 관계의 예제 작업을 보여주는 데 사용됩니다.
먼저 단일 테이블 작업을 살펴 보겠습니다
1. 스프링 데이터 JPA를 사용하십시오
Spring Data JPA에서 제공하는 querydsl 함수를 사용하려면 인터페이스를 직접 상속하는 것은 매우 간단합니다. Spring Data JPA는 다음과 같이 QueryDsl Query 작동 인터페이스를 지원하는 데 사용되는 QueryDslPrediceExecutor 인터페이스를 제공합니다.
패키지 com.chhliu.springboot.jpa.repository; import org.springframework.data.jpa.repository.jparepository; org.springframework.data.querydsl.querydslpredicateExecutor; import com.chhliu.springboot.jpa.entity.user; public interface userreepositoryDls 확장 jparePository <User, Integer>, QueryDslPrediceExecutor <user> {// Inheritance Interface}QueryDslPrediceExecutor 인터페이스는 다음 방법을 제공합니다.
공개 인터페이스 querydslprediceExecutor <t> {t findone (Preticate Predict); 반복 가능한 <t> findall (Predicate Predict, Sort Sort); 반복 가능한 <t> findall (Predicate Predict, OrdersPecifier <?> ... 주문); 반복 가능한 <t> findall (OrdersPecifier <?> ... 주문); page <t> findall (술어 예측, pagable pagable); 긴 카운트 (술어 예측); 부울이 존재한다 (술어 술어); } 상기 방법의 사용은 스프링 데이터 JPA의 다른 인터페이스 사용 방법과 유사합니다. 자세한 내용은 http://www.vevb.com/article/137757.htm을 참조하십시오
테스트는 다음과 같습니다.
공개 사용자 findUserByUserName (Final String username) { / ** *이 예제는 Spring Data QueryDSL을 사용하여 * / QUSER QUSER = QUSER.USER; 술어 percticate = quser.name.eq (username); // 사용자 이름에 따라 사용자 테이블 return repository.findone (presctice); }해당 SQL은 다음과 같습니다.
코드 사본은 다음과 같습니다. user0_.id as as id1_5_, user0_.address as address2_5_, user0_.age as aged3_5_, user0_.name as t_user user0_에서 user0_.name =?
단일 테이블 작동 예제 코드는 다음과 같습니다.
패키지 com.chhliu.springboot.jpa.repository; Java.util.list 가져 오기; import javax.persistence.entitymanager; import javax.persistence.persistenceContext; import javax.persistence.query; import javax.transaction.transactional; org.springframework.beans.factory.annotation.autowired; import org.springframework.data.domain.pagerequest; org.springframework.data.domain.sort import; org.springframework.steretype.component import; import com.chhliu.springboot.jpa.entity.quser; import com.chhliu.springboot.jpa.entity.user; com.querydsl.core.types.predicate import; import com.querydsl.jpa.impl.jpaQueryFactory; / ** * 설명 : QueryDsl jpa * @author chhliu */ @component @transactional public class userrepository managerdsl {@autowired private userrepositoryDls 리포지토리; @autowired @persistenceContext Private EntityManager entityManager; 개인 jpaqueryfactory queryfactory; @PostConstruct public void init () {QueryFactory = new JPAQueryFactory (entityManager); } 공개 사용자 findUserByUserName (Final String username) { / ** *이 예제는 Spring Data QueryDSL을 사용하여 * / QUSER QUSER = QUSER.USER; 술어 predict = Quser.name.eq (사용자 이름); return repository.findone (술어); } / ***주의 :* 세부 사항 : 사용자 테이블의 모든 레코드 쿼리* / public list <user> findall () {Quser Quser = Quser.user; return queryFactory.SelectFrom (Quser) .fetch (); } / *** 세부 사항 : 단일 조건 쿼리* / 공개 사용자 findOneByUserName (Final String username) {Quser Quser = Quser.user; return QueryFactory.SelectFrom (Quser) .where (QUSER.name.eq (username)) .fetchone (); } / *** 세부 사항 : 단일 테이블 다중 조건 쿼리* / 공개 사용자 FindOneByUserNameAndAddress (최종 문자열 사용자 이름, 최종 문자열 주소) {QUSER QUSER = QUSER.USER; return queryfactory.select (Quser) .from (Quser) // 위의 두 문장은 selectfrom.where (Quser.name.eq (username). } / *** 세부 사항 : 조인 쿼리* / public list <user> findUsersByJoin () {QUSER QUSER = QUSER.USER; Quser username = new Quser ( "이름"); 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) .where (Quser.name.eq (username)). execute (); } / *** 세부 사항 : 레코드 업데이트* / public long updateUser (최종 사용자 U, 최종 문자열 사용자 이름) {Quser Quser = Quser.user; return QueryFactory.update (Quser) .where (Quser.name.eq (username)) .set (quser.name, u.getname ()) .set (quser.age, u.getage ()) .set (quser.address, u.getAddress ()); } / ** * 세부 사항 : 기본 쿼리 사용 * / 공개 사용자 findOneUserByOriginalSql (Final String username) {Quser Quser = Quser.user; query query = queryfactory.selectfrom (Quser) .where (quer.name.eq (username)). createquery (); return (user) query.getsingleresult (); } / *** 세부 사항 : Pagination Query 단일 테이블* / public page <user> findAllAndPager (Final int Offset, Final int Pagesize) {Preticate Precticate = Quser.user.id.lt (10); Sort Sort = New Sort (new Sort.Order (Sort.Direction.desc, "id")); Pagerequest Pr = New PageRequest (오프셋, Pagesize, Sort); return repository.findall (Predicate, Pr); }}다중 테이블 작동 예제 (일대일)는 다음과 같습니다.
패키지 com.chhliu.springboot.jpa.repository; java.util.arraylist 가져 오기; Java.util.list 가져 오기; import javax.annotation.postConstruct; import javax.persistence.entitymanager; import javax.persistence.persistenceContext; org.springframework.beans.factory.annotation.autowired; org.springframework.stereotyp.component import; 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; com.querydsl.core.types.predicate import; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaQueryFactory; @Component Public Class PersonAnandidCardManager {@autowired @PersistEnceContext Private EntityManager EntityManager; 개인 jpaqueryfactory queryfactory; @PostConstruct public void init () {QueryFactory = new JPAQueryFactory (entityManager); } / *** 세부 사항 : 다중 테이블 동적 쿼리* / public list <Tuple> findAllPersonAndIdCard () {Preticate Precticate = (qperson.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 (); } / *** 세부 사항 : 출력 쿼리 결과 dto* / public list <personidcarddto> findBydto () {presctice predict = (qperson.person.id.intvalue ()). jpaquery <tuple> jpaquery = queryfactory.select (qidcard.idcard.idno, qperson.person.address, qperson.person.name) .from (qidcard.idcard, qperson.person). List <Tuple> 튜플 = jpaquery.fetch (); 목록 <PersonIdCardDto> dtos = new ArrayList <PersonIdCardDto> (); if (null! = tuples &&! tuples.isempty ()) {for (tuple tuple : tuples) {String address = tuple.get (qperson.person.address); 문자열 이름 = tuple.get (qperson.person.name); String idcard = tuple.get (qidcard.idcard.idno); personIdcarddto dto = new personIdcarddto (); dto.setAddress (주소); dto.setidno (idcard); dto.setName (이름); dtos.add (dto); }} 반환 dtos; } / *** 세부 사항 : 다중 테이블 동적 쿼리 및 페이지 매김* / public queryResults <Tuple> findByDtoAndPager (int offset, int pagesize) {predicate predicate = (qperson.person.id.intvalue ()). return queryFactory.Select (qidcard.idcard.idno, qperson.person.address, qperson.person.name) .from (qidcard.idcard, qperson.person) .where (prescetice) .limit (pagesize) .fetchresults (); }}쿼리 결과가 DTO 모드에서 출력되는 위의 예에서 쿼리가 완료된 후 쿼리 결과가 DTO 객체로 수동으로 변환됩니다. 이 방법은 실제로 매우 우아하지 않습니다. querydsl은 더 나은 방법을 제공합니다. 다음 예를 참조하십시오.
/ *** 세부 사항 : 메소드 1 : Bean Projection*/ public list <personIdcarddto> findBydTouseBean () {Preticate Percedicate = (qperson.person.id.intValue ()). return queryfactory.select (projections.bean (personIdcarddto.class, qidcard.idcard.idno, qperson.person.address, qperson.person.name)) } / ** * 세부 사항 : 메소드 2 : setter 대신 필드를 사용합니다 * / public list <perialidcarddto> findBydTouseFields () {Presctice predict = (qperson.person.id.intvalue ()). return queryFactory.Select (projections.fields (personIdcarddto.class, qidcard.idcard.idno, qperson.person.person.address, qperson.person.name) .from (qidcard.idcard, qperson.person) .fetch (pretch) .fetch (pretch); } / *** 세부 사항 : 메소드 3 : 생성자 메소드를 사용하여 생성자의 속성 순서는 생성자* / 공개 목록의 순서와 일치해야합니다.* / public list <personIdcarddto> findByDtouseConstructor () {preticate predict = (qperson.person.id.intvalue ()). return queryfactory.select (projections.constructor (personidCarddto.class, qperson.person.name, qperson.person.address, qidcard.idcard.idno)) } 위는 몇 가지 아이디어 만 제공합니다. 물론 @QueryProjection을 사용하여이를 구현할 수도 있습니다. 이는 매우 유연합니다.
일회성 예 :
패키지 com.chhliu.springboot.jpa.repository; Java.util.list 가져 오기; import javax.annotation.postConstruct; import javax.persistence.entitymanager; import javax.persistence.persistenceContext; org.springframework.beans.factory.annotation.autowired; org.springframework.stereotyp.component import; import com.chhliu.springboot.jpa.entity.qorder; import com.chhliu.springboot.jpa.entity.qorderitem; import com.querydsl.core.tuple; com.querydsl.core.types.predicate import; import com.querydsl.jpa.impl.jpaquery; import com.querydsl.jpa.impl.jpaQueryFactory; @Component Public Class OrderAndordOritemManager {@autowired @persistenceContext Private EntityManager entityManager; 개인 jpaqueryfactory queryfactory; @PostConstruct public void init () {QueryFactory = new JPAQueryFactory (entityManager); } /*** 세부 사항 : 일대일, 조건부 쿼리* /public list <Tuple> findOrderAndOrdOrdOritEMByOrdame (String OrderName) {// 쿼리 조건 추가 술어 predicate = qorder.ordername.eq (OrderName); jpaquery <tuple> jpaquery = queryfactory.select (Qorder.order, QorderItem.orderItem) .from (Qorder.order, QorderItem.orderItem) .where (QorderItem.orderItem.order.Id.IntValue (). // 결과를 가져옵니다. jpaquery.fetch (); } /*** 세부 사항 : 다중 테이블 조인 쿼리* /공개 목록 <Tuple> findAllByOrderName (String OrderName) {// 쿼리 조건 추가 술어 predicate = qorder.order.ordername.eq (OrderName); jpaquery <tuple> jpaquery = queryfactory.select (Qorder.order, QorderItem.orderItem) .from (Qorder.Order, QORDERITEM.OrderItem) .rightJoin (QORDER.ORDER) .on (QORDERITEM.ORDER.ID.INTVALUE (). jpaquery.where (술어); // 결과를 가져옵니다. jpaquery.fetch (); }} 위의 예에서 QueryDsl이 운영을 크게 단순화했음을 알 수 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.