1. 程式人生 > 程式設計 >Querydsl-JPA學習(入門篇)

Querydsl-JPA學習(入門篇)

1.Querydsl-JPA簡介:

Springdata-JPA是對JPA使用的封裝,Querydsl-JPA也是基於各種ORM之上的一個通用查詢框架,使用它的API類庫可以寫出“Java程式碼的sql”,不用去手動接觸sql語句,表達含義卻如sql般準確。更重要的一點,它能夠構建型別安全的查詢,這比起JPA使用原生查詢時有很大的不同,我們可以不必再對噁心的“Object[]”進行操作了。當然,我們可以SpringDataJPA +Querydsl-JPA聯合使用,它們之間有著完美的相互支援,以達到更高效的編碼。

官網地址:http://www.querydsl.com/
gitub地址:https://github.com/querydsl/querydsl/tree/master/querydsl-jpa
複製程式碼

2.spring boot配置 Querydsl-JPA:

2.1:新增jar包:

 <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <scope>provided</scope>
        </dependency>
複製程式碼

2.2:新增外掛:

作用:對帶有@Entity註解的實體類生成Q版實體類

 <!-- query dsl 構建Q版實體類的外掛-->
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
複製程式碼

2.3:JPAQueryFactory配置:

作用:使用QueryDSL的功能時,會依賴使用到JPAQueryFactory,而JPAQueryFactory在這裡依賴使用EntityManager,所以在主類中做如下配置,使得Spring自動幫我們注入EntityManager與自動管理JPAQueryFactory

import javax.persistence.EntityManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.querydsl.jpa.impl.JPAQueryFactory;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {    
    @Bean
    public JPAQueryFactory jpaQuery(EntityManager entityManager) {
        return new JPAQueryFactory(entityManager);
    }
}    
複製程式碼

2.4:使用bean注入:

    @Autowired
    private JPAQueryFactory jpaQueryFactory;
複製程式碼

2.5:maven構建操作:

3.Querydsl-JPA單表操作:

3.1 新增實體類:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.math.BigDecimal;
import java.sql.Timestamp;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@Table(name = "user_tmw")
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO,generator = "custom-uuid")
    @GenericGenerator(name = "custom-uuid",strategy = "com.springboot.demo.bean.CustomUUIDGenerator")
    @Column(name = "id",nullable = false,length = 32)
    private String id;

    @Column(name = "name",length = 10)
    private String name;

    @Column(name = "age")
    private Integer age;

    @Column(name = "money")
    private BigDecimal money;

    @Column(name = "begin_time")
    private Timestamp beginTime;

    @Column(name = "end_time")
    private Timestamp endTime;
}
複製程式碼

3.2 等於某個值的結果集:

    QUser user = QUser.user;
    //單表獲取年齡為10的結果集
    List<User> ageList = jpaQueryFactory.selectFrom(user).where(user.age.eq(10)).fetch();
    String ageListStr = JSON.toJSONString(ageList);
    System.out.println("單表獲取年齡為10的結果集:"+ageListStr);

複製程式碼

3.3 等於某個值查詢單個:fetchFirst的用法:

    QUser user = QUser.user;
    //fetchFirst的用法: 單表獲取年齡為10的首個結果
    User user1 = jpaQueryFactory.selectFrom(user).where(user.age.eq(10)).fetchFirst();
    System.out.println("單表獲取年齡為10的首個結果:"+user1.toString());

複製程式碼

3.4 模糊檢索的用法1(like關鍵字):

    QUser user = QUser.user;
    //模糊檢索的用法:單表獲取名稱包含小的使用者並且按照年齡倒排序
    List<User> nameList = jpaQueryFactory.selectFrom(user).where(user.name.like("%小%")).orderBy(user.age.desc()).fetch();
    String nameListStr = JSON.toJSONString(nameList);
    System.out.println("單表獲取名稱包含小的使用者並且按照年齡倒排序的結果集:"+nameListStr);

複製程式碼

3.5 模糊檢索的用法2(startsWith):

    QUser user = QUser.user;
    //模糊檢索的用法:單表獲取名稱是以小開頭的使用者並且按照年齡正序排
    List<User> nameAscList = jpaQueryFactory.selectFrom(user).where(user.name.startsWith("小")).orderBy(user.age.asc()).fetch();
    String nameAscListStr = JSON.toJSONString(nameAscList);
    System.out.println("單表獲取名稱是以小開頭的使用者並且按照年齡正序排的結果集:"+nameAscListStr);
複製程式碼

3.6 區間用法(between):

    QUser user = QUser.user;
    //between 區間的用法:單表獲取開始時間是XX-XX 區間的使用者
    String time = "2019-07-22 00:00:00";
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date= df.parse(time);
    Timestamp nousedate = new Timestamp(date.getTime());

    String time1 = "2019-07-23 00:00:00";
    Date date1= df.parse(time1);
    Timestamp nousedate1 = new Timestamp(date1.getTime());

    List<User> beginTimeList = jpaQueryFactory.selectFrom(user).where(user.beginTime.between(nousedate,nousedate1)).fetch();
    String beginTimeListStr = JSON.toJSONString(beginTimeList);
    System.out.println("單表獲取開始時間是XX-XX 區間的使用者的結果集:"+beginTimeListStr);

複製程式碼

3.7 in的用法:

    QUser user = QUser.user;
    //in 的用法:單表獲取年齡是10,20的使用者
    List<Integer> ageLists = new ArrayList<>();
    ageLists.add(10);
    ageLists.add(20);
    List<User> ages = jpaQueryFactory.selectFrom(user).where(user.age.in(ageLists)).fetch();
    String agesStr = JSON.toJSONString(ages);
    System.out.println("單表獲取年齡是10,20的使用者的結果集:"+agesStr);

複製程式碼

3.8 聚合函式max,avg,min的用法:

    QUser user = QUser.user;
    //聚合函式-concat()的使用:單表查詢將使用者id,名稱,年齡拼接的結果
    List<String> concatList = jpaQueryFactory.select(user.id.concat(user.name).concat(user.age.stringValue())).from(user).fetch();
    String concatListStr = JSON.toJSONString(concatList);
    System.out.println("單表查詢將使用者id,名稱,年齡拼接的結果:"+concatListStr);

複製程式碼

3.9 聚合函式groupby的用法:

    QUser user = QUser.user;
    List<Map<String,Object>> tupleJPAQuery = jpaQueryFactory.select(user.age,user.count().as("count")).from(user).groupBy(user.age)
        .fetch().stream().map(x->{
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("age",x.get(0,QUser.class));
            resultMap.put("count",x.get(1,QUser.class));
            return resultMap;
        }).collect(Collectors.toList());
    
    String userQueryResultsStr = JSON.toJSONString(tupleJPAQuery);
    System.out.println("單表分組的結果集:"+userQueryResultsStr);
    
複製程式碼

3.10 多條件拼接的使用(BooleanBuilder):

    QUser user = QUser.user;
    //多條件處理
    BooleanBuilder booleanBuilder = new BooleanBuilder();
    booleanBuilder.and(user.age.eq(10));
    booleanBuilder.and(user.name.contains("小"));
    List<User> mostlist = jpaQueryFactory.selectFrom(user).where(booleanBuilder).fetch();
    String mostlistStr = JSON.toJSONString(mostlist);
    System.out.println("單表查詢多條件處理的結果:"+mostlistStr);

複製程式碼

3.11 分頁查詢的處理:

    QUser user = QUser.user;
    QueryResults<User> userQueryResults =
    jpaQueryFactory.selectFrom(user).offset(0).limit(2).fetchResults();
    String userQueryResultsStr = JSON.toJSONString(userQueryResults);
    System.out.println("單表分頁的結果集:"+userQueryResultsStr);

複製程式碼