Springdata-JPA是對JPA使用的封裝,Querydsl-JPA也是基於各類ORM之上的一個通用查詢框架,使用它的API類庫能夠寫出「Java代碼的sql」,不用去手動接觸sql語句,表達含義卻如sql般準確。更重要的一點,它可以構建類型安全的查詢,這比起JPA使用原生查詢時有很大的不一樣,咱們能夠沒必要再對噁心的「Object[]」進行操做了。固然,咱們能夠SpringDataJPA +Querydsl-JPA聯合使用,它們之間有着完美的相互支持,以達到更高效的編碼。java
官網地址:http://www.querydsl.com/
gitub地址:https://github.com/querydsl/querydsl/tree/master/querydsl-jpa
複製代碼
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
複製代碼
做用:對帶有@Entity註解的實體類生成Q版實體類git
<!-- 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>
複製代碼
做用:使用QueryDSL的功能時,會依賴使用到JPAQueryFactory,而JPAQueryFactory在這裏依賴使用EntityManager,因此在主類中作以下配置,使得Spring自動幫咱們注入EntityManager與自動管理JPAQueryFactorygithub
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);
}
}
複製代碼
@Autowired
private JPAQueryFactory jpaQueryFactory;
複製代碼
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;
}
複製代碼
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);
複製代碼
QUser user = QUser.user;
//fetchFirst的用法: 單表獲取年齡爲10的首個結果
User user1 = jpaQueryFactory.selectFrom(user).where(user.age.eq(10)).fetchFirst();
System.out.println("單表獲取年齡爲10的首個結果:"+user1.toString());
複製代碼
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);
複製代碼
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);
複製代碼
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);
複製代碼
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);
複製代碼
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);
複製代碼
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);
複製代碼
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);
複製代碼
QUser user = QUser.user;
QueryResults<User> userQueryResults =
jpaQueryFactory.selectFrom(user).offset(0).limit(2).fetchResults();
String userQueryResultsStr = JSON.toJSONString(userQueryResults);
System.out.println("單表分頁的結果集:"+userQueryResultsStr);
複製代碼