您好,登錄后才能下訂單哦!
這篇文章給大家介紹SpringJPA中QueryDSL如何使用,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
項目整合
pom文件配置
QueryDSL
本身定位就是對某些技術的補充或者說是完善,其提供了對JPA
、JDBC
、JDO
等技術的支持。這里引入的是QueryDSL-JPA
,需要注意一定要引入querydsl代碼生成器插件。
<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>
application配置文件
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 */@Configurationpublic 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;@SpringBootApplicationpublic 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@Entitypublic 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@Entitypublic class Lecturer { /** * 講師ID */ @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Long id; /** * 講師名字 */ private String name; /** * 性別,true(1)為男性,false(0)為女性 */ private Boolean sex;}
Repository接口
如果要使用QuerDSL
需要Repository
接口除了繼承JpaRepository
接口(此接口為Spring-JPA
提供的接口)外,還需要繼承QuerydslPredicateExecutor
接口。關鍵示例如下:
課程Repository
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> {}
講師Repository
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> {}
代碼生成
前面配置QueryDSL
代碼生成器就是用于這一步,==每次實體類有變更最好重復執行本步驟重新生成新的代碼==。由于個人習慣使用IDEA
,所以以IDEA
作為演示。
雙擊下圖內容即可生成代碼了,
然后就會在src/generated-sources
目錄可以看到生成的代碼,包名與實體包名一致,但是類名為Q
開頭的文件
上一步的截圖我們可以看到其實生成的代碼被IDEA
識別為普通文件了,所以我們需要標記src/generated-sources/java
目錄的用途,如下圖所示
標記后,效果如下,可以看到代碼被正確識別了
到了這一步其實已經完成整合了,下面就開始驗證是否正確整合以及展示QueryDSL
的優勢了
驗證整合與演示
下面我會使用單元測試來驗證QueryDSL
是否正確整合以及演示一下QueryDSL
的優勢
單元測試類
這里主要是單元測試類的關鍵內容,需要注意@BeforeEach
是Junit5
的注解,表示每個單元測試用例執行前會執行的方法其實對應Junit4
的@Before
/** * @SpringBootTest 默認不支持事務且自動回滾 * 使用@Transactional 開啟事務, * 使用@Rollback(false) 關閉自動回滾 * @author Null * @date 2019-10-24 */@SpringBootTestclass 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); }
用例分析
從用例中可以看出其實QueryDSL
的API
更加切合原生的SQL
,基本上從代碼上就可以看出你希望執行的SQL
了。
細心的朋友會發現QueryDSL
是沒有insert
方法,因為JPA
提供的save()
方法已經足夠處理了。
同時要記得要組裝好你的SQL
后別忘記調用fetch()
或者execute()
方法。
總結
Spring Boot JPA
整合QueryDSL
的關鍵步驟
引入依賴和插件 編寫配置類 使用插件生成代碼 標記生成文件為代碼 Repository繼承QuerydslPredicateExecutor
QueryDSL
的API
類似原生SQL
,API
風格類似StringBuilder
的API
(Fluent API
風格)。但是不提供insert
對應的操作。
QueryDSL
對于復雜的SQL
的支持十分友好,算是對于JPA
對這塊需求的補充和完善。
關于SpringJPA中QueryDSL如何使用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。