Spring JPA 통합 Query DSL 의 예제 코드

14808 단어 SpringJPAQueryDSL
머리말Spring JPA는 현재 비교적 자주 사용 되 는ORM해결 방안 이지 만 일부 장면 에 대해 특별한 편리 함 이 없다.예 를 들 어 일부 필드 조회,연결 표 조회,서브 조회 등 이다.
다음은JPA와 상호 보완 을 이 루 는 동시에JPA와 잘 호 환 되 는 프레임 워 크QueryDSL를 소개 하 겠 습 니 다.
또한 현재 주류 사용Spring Boot이기 때문에 본 고 는Spring Boot을 바탕 으로 시연 할 것 이다.
만약 에 장문 에 대해 무감각 하지만 이해 하고 싶다 면QueryDSL문장의 마지막 총 결 을 직접 볼 수 있다.
환경 정보
다음은 예시 적 인 관건 적 인 환경 정보 이다.
  • JDK 1.8
  • maven 3.6.1
  • SpringBoot 2.2.0.RELEASE
  • IntelliJ IDEA 2019.2.3
  • lombok
  • mysql-5.7
  • 원본 주소
    https://github.com/spring-based-solutions/querydsl-jpa-demo
    프로젝트 통합
    pom 파일 설정QueryDSL자체 의 포 지 셔 닝 은 특정한 기술 에 대한 보충 또는 보완 이 고JPA,JDBC,JDO등 기술 에 대한 지원 을 제공 했다.여기에 도 입 된 것 은QueryDSL-JPA입 니 다.query dsl 코드 생 성기 플러그 인 을 반드시 도입 해 야 합 니 다.
    
      <properties>
        <java.version>1.8</java.version>
        <querydsl.version>4.2.1</querydsl.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--       mysql   ,    mysql-5.7-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.48</version>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-configuration-processor</artifactId>
          <optional>true</optional>
        </dependency>
        <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <optional>true</optional>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
          <exclusions>
            <exclusion>
              <groupId>org.junit.vintage</groupId>
              <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
          </exclusions>
        </dependency>
    
        <!--  querydsl-jpa  -->
        <dependency>
          <groupId>com.querydsl</groupId>
          <artifactId>querydsl-jpa</artifactId>
          <version>${querydsl.version}</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
          <!--  querydsl       -->
          <plugin>
            <groupId>com.mysema.maven</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <version>1.1.3</version>
            <dependencies>
              <dependency>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-apt</artifactId>
                <version>${querydsl.version}</version>
              </dependency>
            </dependencies>
            <executions>
              <!--       maven    -->
              <execution>
                <goals>
                  <goal>process</goal>
                </goals>
                <configuration>
                  <!--         --> 
                  <outputDirectory>src/generated-sources/java/</outputDirectory>
                  <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    응용 프로그램 프로필
    
    spring:
     datasource:
      ##        
      url: jdbc:mysql://127.0.0.1:3306/example?useSSL=false
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver #      
     jpa:
      hibernate:
       ddl-auto: update #             ,      
      show-sql: true #      SQL
    설정 클래스QueryDSL제공 되 지 않 기 때문에starter자체 적 으로 설정 류 를 준비 해 야 합 니 다.코드 는 다음 과 같 습 니 다.
    
    import com.querydsl.jpa.impl.JPAQueryFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    /**
     * QueryDSL   
     * @author Null
     * @date 2019-10-24
     */
    @Configuration
    public class QuerydslConfig {
    
      @Autowired
      @PersistenceContext
      private EntityManager entityManager;
    
      @Bean
      public JPAQueryFactory queryFactory(){
        return new JPAQueryFactory(entityManager);
      }
    
    }
    시작 클래스
    시작 클래스 는 간단 합 니 다.@SpringBootApplication만 사용 하면 됩 니 다.
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class QuerydslJpaDemoApplication {
    
      public static void main(String[] args) {
        SpringApplication.run(QuerydslJpaDemoApplication.class, args);
      }
    }
    실체 류
    주로 강사 와 과정 이 있 고 모든 과정 에 강사 가 한 명 있 으 며 모든 강 사 는 여러 개의 과정 이 있다.즉,강사 와 과정의 관 계 는 한 쌍 이 많다.
    교과 과정
    
    import lombok.Data;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**
     *   ,          
     * @author Null
     * @date 2019-10-24
     */
    @Data
    @Entity
    public class Course {
      /**
       *   ID
       */
      @Id
      @GeneratedValue(strategy= GenerationType.IDENTITY)
      private Long id;
      /**
       *     
       */
      private String name;
      /**
       *      ID
       */
      private Long lecturerId;
    }
    강사
    
    import lombok.Data;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**
     *   ,         
     * @author Null
     * @date 2019-10-24
     */
    @Data
    @Entity
    public class Lecturer {
      /**
       *   ID
       */
      @Id
      @GeneratedValue(strategy= GenerationType.IDENTITY)
      private Long id;
      /**
       *     
       */
      private String name;
      /**
       *   ,true(1)   ,false(0)   
       */
      private Boolean sex;
    }
    저장 소 인터페이스QuerDSL인 터 페 이 스 를 사용 하려 면 계승Repository인터페이스(이 인 터 페 이 스 는JpaRepository가 제공 하 는 인터페이스)외 에 도 계승Spring-JPA인터페이스 가 필요 하 다.관건 적 인 예 는 다음 과 같다.
    과정 저장 소
    
    import com.example.querydsl.jpa.entity.Course;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.querydsl.QuerydslPredicateExecutor;
    
    /**
     *   Repository
     *
     * @author Null
     * @date 2019-10-24
     */
    public interface CourseRepository extends
        JpaRepository<Course, Integer>,
        QuerydslPredicateExecutor<Course> {
    }
    강사 저장 소
    
    import com.example.querydsl.jpa.entity.Lecturer;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.querydsl.QuerydslPredicateExecutor;
    
    /**
     *   Repository
     * @author Null
     * @date 2019-10-24
     */
    public interface LecturerRepository extends
        JpaRepository<Lecturer,Integer>,
        QuerydslPredicateExecutor<Lecturer> {
    }
    코드 생 성
    앞의 설정QuerydslPredicateExecutor코드 생 성 기 는 이 단계 에 사 용 됩 니 다.개인 적 인 습관QueryDSL을 사용 하기 때문에IDEA을 시연 으로 한다.
    다음 그림 내용 을 더 블 클릭 하면 코드 를 생 성 할 수 있 습 니 다.

    그리고IDEA디 렉 터 리 에서 생 성 된 코드 를 볼 수 있 습 니 다.패키지 이름 은 실체 패키지 이름과 일치 하지만 클래스 이름src/generated-sources으로 시작 하 는 파일 입 니 다.

    이전 캡 처 에서 우 리 는 실제 생 성 된 코드 가Q일반 파일 로 인식 되 었 기 때문에 우 리 는IDEA디 렉 터 리 의 용 도 를 표시 해 야 한다.아래 그림 과 같다.

    표 시 된 후 효 과 는 다음 과 같 습 니 다.코드 가 정확하게 식별 되 는 것 을 볼 수 있 습 니 다.

    이 단계 에 이 르 러 통합 이 완료 되 었 습 니 다.다음은 정확 한 통합 과 전시src/generated-sources/java의 장점 을 검증 하 겠 습 니 다.
    통합 및 프레젠테이션 검증
    다음은 유닛 테스트 를 통 해QueryDSL의 정확 한 통합 여 부 를 검증 하고QueryDSL의 장점 을 보 여 드 리 겠 습 니 다.
    유닛 테스트 클래스
    여 기 는 주로 단원 테스트 류 의 관건 적 인 내용 으로 주의해 야 한다QueryDSL@BeforeEach의 주해 로 각 단원 테스트 용례 가 집행 되 기 전에 집행 하 는 방법 이 사실 대응Junit5한 다 는 것 을 나타 낸다Junit4
    
    /**
     * @SpringBootTest             
     *   @Transactional     ,
     *   @Rollback(false)       
     * @author Null
     * @date 2019-10-24
     */
    @SpringBootTest
    class QuerydslJpaDemoApplicationTests {
    
      @Autowired
      private CourseRepository courseRepository;
    
      @Autowired
      private LecturerRepository lecturerRepository;
      
      @Autowired
      private JPAQueryFactory queryFactory;
    
      /**
       *      
       */
      @BeforeEach
      public void initData(){
        //      
        courseRepository.deleteAll();
        lecturerRepository.deleteAll();
    
        //      
        Lecturer tom=new Lecturer();
        tom.setName("Tom");
        tom.setSex(true);
        lecturerRepository.save(tom);
    
        Lecturer marry=new Lecturer();
        marry.setName("Marry");
        marry.setSex(false);
        lecturerRepository.save(marry);
    
        //      
        Course chinese=new Course();
        chinese.setName("Chinese");
        chinese.setLecturerId(tom.getId());
        courseRepository.save(chinese);
    
        Course physics=new Course();
        physics.setName("Physics");
        physics.setLecturerId(tom.getId());
        courseRepository.save(physics);
    
        Course english=new Course();
        english.setName("English");
        english.setLecturerId(marry.getId());
        courseRepository.save(english);
      }
      
      ...      
      
    }
    단일 표 모호 조회
    
      /**
       *             
       */
      @Test
      public void testSelectCourseByNameLike() {
        //       
        QCourse qCourse = QCourse.course;
        // %     
        BooleanExpression expression = qCourse.name.like("P%");
        System.out.println(courseRepository.findAll(expression));
      }
    리스트 조회
    
      /**
       *          
       */
      @Test
      public void testSelectCourseByLecturerName(){
        QCourse qCourse = QCourse.course;
        QLecturer qLecturer = QLecturer.lecturer;
        //                    ,          fetch()
        List<Course> courses=queryFactory.select(qCourse)
            .from(qCourse)
            .leftJoin(qLecturer)
            .on(qCourse.lecturerId.eq(qLecturer.id))
            .where(qLecturer.name.eq("Tom"))
            .fetch();
        System.out.println(courses);
      }
    
    업데이트
    
      /**
       *           <br/>
       *   @Transactional    <br/>
       *   @Rollback(false)      <br/>
       */
      @Test
      @Transactional
      @Rollback(false)
      public void testUpdateLecturerSexByName(){
        QLecturer qLecturer = QLecturer.lecturer;
        //   Tom      ,          
        long num=queryFactory.update(qLecturer)
            .set(qLecturer.sex,false)
            .where(qLecturer.name.eq("Tom"))
            .execute();
        //            
        System.out.println(num);
      }
    삭제
    
      /**
       *           
       */
      @Test
      @Transactional
      @Rollback(false)
      public void testDeleteLecturerBySex(){
        QLecturer qLecturer = QLecturer.lecturer;
        //           
        long num=queryFactory.delete(qLecturer)
            .where(qLecturer.sex.eq(true))
            .execute();
        //          
        System.out.println(num);
      }
    용례 분석
    사례 를 통 해 알 수 있 듯 이 사실@BeforeQueryDSL은 원생API에 더욱 부합 되 고 대체적으로 코드 에서 네가 집행 하고 자 하 는SQL을 알 수 있다.
    세심 한 친구 들 은SQL방법 이 없다 는 것 을 알 게 될 것 이다.QueryDSL제공 하 는insert방법 은 이미 충분히 처리 되 었 기 때문이다.
    동시에 당신 의JPA을 조립 한 후에 호출save()이나SQL방법 을 잊 지 마 세 요.
    총결산fetch()통합execute()의 관건 적 인 절차
  • 의존 과 플러그 인 도입
  • 설정 클래스 작성
  • 플러그 인 을 사용 하여 코드 생 성
  • 태그 생 성 파일 을 코드
  • 로 표시 합 니 다.
  • QuerydslPredicateExecutor
  • Spring Boot JPAQueryDSL는 원생QueryDSL과 비슷 하고API스타일 은 비슷 하 다SQLAPIStringBuilder.그러나 대응 하 는 조작 은 제공 되 지 않 는 다.API복잡 한Fluent API에 대한 지 지 는 매우 우호 적 이 고insert이 수요 에 대한 보충 과 보완 이 라 고 할 수 있다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기