這篇文章將為大家詳細(xì)講解有關(guān)QueryDSL如何在Spring JPA中使用,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
員工經(jīng)過長期磨合與沉淀,具備了協(xié)作精神,得以通過團(tuán)隊(duì)的力量開發(fā)出優(yōu)質(zhì)的產(chǎn)品。創(chuàng)新互聯(lián)建站堅(jiān)持“專注、創(chuàng)新、易用”的產(chǎn)品理念,因?yàn)椤皩W⑺詫I(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡單”。公司專注于為企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作、微信公眾號(hào)開發(fā)、電商網(wǎng)站開發(fā),小程序開發(fā),軟件按需設(shè)計(jì)等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。
pom文件配置
QueryDSL
本身定位就是對(duì)某些技術(shù)的補(bǔ)充或者說是完善,其提供了對(duì)JPA
、JDBC
、JDO
等技術(shù)的支持。這里引入的是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驅(qū)動(dòng)包,用于連接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> <!--設(shè)置插件生效的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: ## 數(shù)據(jù)庫相關(guān)配置 url: jdbc:mysql://127.0.0.1:3306/example?useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver # 指定驅(qū)動(dòng)類 jpa: hibernate: ddl-auto: update # 自動(dòng)創(chuàng)建表以及更新表結(jié)構(gòu),生產(chǎn)環(huán)境慎用 show-sql: true # 打印執(zhí)行的SQL
配置類
由于QueryDSL
不提供starter
,所以需要自行準(zhǔn)備一個(gè)配置類,代碼如下所示
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); } }
啟動(dòng)類
啟動(dòng)類很簡單,只需要使用@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); } }
實(shí)體類
主要有講師和課程,每個(gè)課程都有一個(gè)講師,每個(gè)講師有多個(gè)課程,即講師與課程的關(guān)系為一對(duì)多
課程
import lombok.Data; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; /** * 課程,一個(gè)課程對(duì)應(yīng)一個(gè)講師 * @author Null * @date 2019-10-24 */ @Data @Entity public class Course { /** * 課程ID */ @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Long id; /** * 課程名稱 */ private String name; /** * 對(duì)應(yīng)講師的ID */ private Long lecturerId; }
講師
import lombok.Data; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; /** * 講師,一個(gè)講師有多個(gè)課程 * @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; }
Repository接口
如果要使用QuerDSL
需要Repository
接口除了繼承JpaRepository
接口(此接口為Spring-JPA
提供的接口)外,還需要繼承QuerydslPredicateExecutor
接口。關(guān)鍵示例如下:
課程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
代碼生成器就是用于這一步,==每次實(shí)體類有變更最好重復(fù)執(zhí)行本步驟重新生成新的代碼==。由于個(gè)人習(xí)慣使用IDEA
,所以以IDEA
作為演示。
雙擊下圖內(nèi)容即可生成代碼了,
然后就會(huì)在src/generated-sources
目錄可以看到生成的代碼,包名與實(shí)體包名一致,但是類名為Q
開頭的文件
上一步的截圖我們可以看到其實(shí)生成的代碼被IDEA
識(shí)別為普通文件了,所以我們需要標(biāo)記src/generated-sources/java
目錄的用途,如下圖所示
標(biāo)記后,效果如下,可以看到代碼被正確識(shí)別了
到了這一步其實(shí)已經(jīng)完成整合了,下面就開始驗(yàn)證是否正確整合以及展示QueryDSL
的優(yōu)勢(shì)了
驗(yàn)證整合與演示
下面我會(huì)使用單元測試來驗(yàn)證QueryDSL
是否正確整合以及演示一下QueryDSL
的優(yōu)勢(shì)
單元測試類
這里主要是單元測試類的關(guān)鍵內(nèi)容,需要注意@BeforeEach
是Junit5
的注解,表示每個(gè)單元測試用例執(zhí)行前會(huì)執(zhí)行的方法其實(shí)對(duì)應(yīng)Junit4
的@Before
/** * @SpringBootTest 默認(rèn)不支持事務(wù)且自動(dòng)回滾 * 使用@Transactional 開啟事務(wù), * 使用@Rollback(false) 關(guān)閉自動(dòng)回滾 * @author Null * @date 2019-10-24 */ @SpringBootTest class QuerydslJpaDemoApplicationTests { @Autowired private CourseRepository courseRepository; @Autowired private LecturerRepository lecturerRepository; @Autowired private JPAQueryFactory queryFactory; /** * 初始化數(shù)據(jù) */ @BeforeEach public void initData(){ // 清空數(shù)據(jù)表 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); } ...省略各個(gè)用例 }
單表模糊查詢
/** * 根據(jù)課程名稱模糊查詢課程 */ @Test public void testSelectCourseByNameLike() { // 組裝查詢條件 QCourse qCourse = QCourse.course; // %要自行組裝 BooleanExpression expression = qCourse.name.like("P%"); System.out.println(courseRepository.findAll(expression)); }
聯(lián)表查詢
/** * 根據(jù)講師姓名查課程 */ @Test public void testSelectCourseByLecturerName(){ QCourse qCourse = QCourse.course; QLecturer qLecturer = QLecturer.lecturer; // 這里包含了組裝查詢條件和執(zhí)行查詢的邏輯,組裝好條件后記得執(zhí)行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); }
更新
/** * 根據(jù)姓名更新講師性別<br/> * 使用@Transactional開啟事務(wù)<br/> * 使用@Rollback(false)關(guān)閉自動(dòng)回滾<br/> */ @Test @Transactional @Rollback(false) public void testUpdateLecturerSexByName(){ QLecturer qLecturer = QLecturer.lecturer; // 更新Tom的性別為女性,返回的是影響記錄條數(shù) long num=queryFactory.update(qLecturer) .set(qLecturer.sex,false) .where(qLecturer.name.eq("Tom")) .execute(); // 這里輸出被更新的記錄數(shù) System.out.println(num); }
刪除
/** * 根據(jù)根據(jù)性別刪除講師 */ @Test @Transactional @Rollback(false) public void testDeleteLecturerBySex(){ QLecturer qLecturer = QLecturer.lecturer; // 刪除性別為男性的講師 long num=queryFactory.delete(qLecturer) .where(qLecturer.sex.eq(true)) .execute(); // 輸出被刪除的記錄數(shù) System.out.println(num); }
用例分析
從用例中可以看出其實(shí)QueryDSL
的API
更加切合原生的SQL
,基本上從代碼上就可以看出你希望執(zhí)行的SQL
了。
細(xì)心的朋友會(huì)發(fā)現(xiàn)QueryDSL
是沒有insert
方法,因?yàn)?code>JPA提供的save()
方法已經(jīng)足夠處理了。
同時(shí)要記得要組裝好你的SQL
后別忘記調(diào)用fetch()
或者execute()
方法。
總結(jié)
Spring Boot JPA
整合QueryDSL
的關(guān)鍵步驟
引入依賴和插件
編寫配置類
使用插件生成代碼
標(biāo)記生成文件為代碼
Repository繼承QuerydslPredicateExecutor
QueryDSL
的API
類似原生SQL
,API
風(fēng)格類似StringBuilder
的API
(Fluent API
風(fēng)格)。但是不提供insert
對(duì)應(yīng)的操作。
關(guān)于QueryDSL如何在Spring JPA中使用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
文章題目:QueryDSL如何在SpringJPA中使用
瀏覽地址:http://www.2m8n56k.cn/article48/pecjep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、網(wǎng)站建設(shè)、軟件開發(fā)、虛擬主機(jī)、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站營銷
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)