Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法
【專利摘要】本發(fā)明涉及一種Spring?data?JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其中包括采用基于Spring?FactoryBean創(chuàng)建的動(dòng)態(tài)查詢確認(rèn)類判斷被調(diào)用的接口方法是否需要進(jìn)行動(dòng)態(tài)查詢;采用基于Spring?FactoryBean創(chuàng)建的動(dòng)態(tài)JPA查詢類創(chuàng)建動(dòng)態(tài)查詢語句;所述的動(dòng)態(tài)JPA查詢類將所述的動(dòng)態(tài)查詢語句發(fā)送至JPA框架;所述的動(dòng)態(tài)JPA查詢類將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的返回對(duì)象。采用該種Spring?data?JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,能夠?qū)崿F(xiàn)只需要進(jìn)行接口方法定義聲明,而無需進(jìn)行任何實(shí)際編碼邏輯的實(shí)現(xiàn),如果以后頁面查詢的需求發(fā)生變化,只需要在相應(yīng)的VO類中增加或者修改屬性、注解即可,大大減輕了開發(fā)人員的負(fù)擔(dān),降低了進(jìn)行頁面查詢開發(fā)出錯(cuò)的可能性,增強(qiáng)了軟件的維護(hù)性,提高了軟件開發(fā)的生產(chǎn)力,具有更廣泛的應(yīng)用范圍。
【專利說明】Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及計(jì)算機(jī)【技術(shù)領(lǐng)域】,尤其涉及動(dòng)態(tài)查詢領(lǐng)域,具體是指一種Spring dataJPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法。
【背景技術(shù)】
[0002]Spring data JPA是指一種Spring數(shù)據(jù)持久化架構(gòu),是Spring (—個(gè)開源框架,為了解決企業(yè)應(yīng)用程序開發(fā)復(fù)雜性而創(chuàng)建)基于ORM (Object/Relation Mapping,對(duì)象關(guān)系映射)框架、JPA (Java Persistence API,存取Java關(guān)系數(shù)據(jù)的企業(yè)級(jí)標(biāo)準(zhǔn),JPA通過JDK5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系,并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫中)規(guī)范的基礎(chǔ)上封裝的一套JPA應(yīng)用框架,是一種企業(yè)級(jí)Java的現(xiàn)代數(shù)據(jù)訪問技術(shù),該技術(shù)較完美地將Spring的易用性和JPA的強(qiáng)大數(shù)據(jù)訪問功能結(jié)合起來,開發(fā)者在使用Springdata (是一個(gè)用于簡(jiǎn)化數(shù)據(jù)庫訪問,并支持云服務(wù)的開源框架,針對(duì)關(guān)系型數(shù)據(jù)庫、KV數(shù)據(jù)庫、Document數(shù)據(jù)庫、Graph數(shù)據(jù)庫、Map-Reduce等一些主流數(shù)據(jù)庫,采用統(tǒng)一技術(shù)進(jìn)行訪問,并且盡可能簡(jiǎn)化訪問手段的技術(shù))時(shí),連僅剩的實(shí)現(xiàn)持久層業(yè)務(wù)邏輯的工作都省了,唯一要做的,就只是聲明持久層的接口,其他都交給Spring Data JPA來幫你完成!
[0003]但是Spring data JPA還是有美中不足的地方,就是缺少對(duì)動(dòng)態(tài)查詢功能。在Spring data中,無論是命名查詢還是約定查詢,無論你傳遞的參數(shù)是否為空,框架給你構(gòu)造的查詢條件都是一樣的。
[0004]但是在實(shí)際應(yīng)用中,很多場(chǎng)景都是需要進(jìn)行動(dòng)態(tài)查詢的,尤其是頁面查詢功能。在開發(fā)Web應(yīng)用時(shí),頁面中會(huì)有一系列的查詢條件,如果你輸入了查詢值,就要把該條件加入到查詢語句中,否則,忽略該條件。
[0005]如果使用傳統(tǒng)技術(shù)來進(jìn)行編程,無論使用Hibernate(—種開放源代碼的對(duì)象關(guān)系映射框架)還是JDBC (Java Data Base Connectivity, Java數(shù)據(jù)庫連接),都需要寫大量的邏輯來對(duì)查詢條件進(jìn)行判斷,并且還要根據(jù)返回對(duì)象的屬性從查詢結(jié)果中取值、轉(zhuǎn)換。編程不僅繁瑣易錯(cuò),而且后續(xù)的可維護(hù)性也不強(qiáng)。不具備通用性和靈活性。
[0006]Mybati s3 (支持普通SQL查詢、存儲(chǔ)過程和高級(jí)映射的優(yōu)秀持久層框架)中比較強(qiáng)大的功能之一就是動(dòng)態(tài)SQL (Structured Query Language,結(jié)構(gòu)化查詢語言)語句,類似于腳本語句一樣動(dòng)態(tài)進(jìn)行SQL語句的配置,可以解決這類問題。但是一來這個(gè)需要使用Xml來進(jìn)行配置,并且還是需要寫比較復(fù)雜的腳本,另外整個(gè)編程要使用Mybatis的架構(gòu),對(duì)于使用hibernate或者JPA架構(gòu)的開發(fā)團(tuán)隊(duì)是不適用的。
【發(fā)明內(nèi)容】
[0007]本發(fā)明的目的是克服了上述現(xiàn)有技術(shù)的缺點(diǎn),提供了一種能夠?qū)崿F(xiàn)只需要進(jìn)行接口方法定義聲明、而無需進(jìn)行任何實(shí)際編碼邏輯的實(shí)現(xiàn)、增強(qiáng)軟件的維護(hù)性、提高軟件開發(fā)的生產(chǎn)力、具有更廣泛應(yīng)用范圍的Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法。
[0008]為了實(shí)現(xiàn)上述目的,本發(fā)明的Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法具有如下構(gòu)成:
[0009]該Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其主要特點(diǎn)是,所述的方法包括以下步驟:
[0010](I)采用基于Spring FactoryBean創(chuàng)建的動(dòng)態(tài)查詢確認(rèn)類判斷被調(diào)用的接口方法是否需要進(jìn)行動(dòng)態(tài)查詢,如果是,則繼續(xù)步驟(3),否則,繼續(xù)步驟(2);
[0011](2)采用原Spring data框架處理該被調(diào)用的接口方法,然后結(jié)束退出;
[0012](3)采用基于Spring FactoryBean創(chuàng)建的動(dòng)態(tài)JPA查詢類創(chuàng)建動(dòng)態(tài)查詢語句;
[0013](4)所述的動(dòng)態(tài)JPA查詢類將所述的動(dòng)態(tài)查詢語句發(fā)送至JPA框架;
[0014](5)所述的動(dòng)態(tài)JPA查詢類將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的返回對(duì)象。
[0015]較佳地,所述的判斷被調(diào)用的接口方法是否需要進(jìn)行動(dòng)態(tài)查詢,具體為:
[0016]判斷被調(diào)用的接口方法是否進(jìn)行了動(dòng)態(tài)JPA查詢類的注解。
[0017]較佳地,所述的動(dòng)態(tài)JPA查詢類創(chuàng)建動(dòng)態(tài)查詢語句,具體為:
[0018](31)所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法中的參數(shù)定義以及進(jìn)行接口方法調(diào)用的實(shí)際傳遞參數(shù)值創(chuàng)建動(dòng)態(tài)查詢語句中的條件語句。
[0019]更佳地,所述的根據(jù)接口方法中的參數(shù)定義以及進(jìn)行接口方法調(diào)用的實(shí)際傳遞參數(shù)值創(chuàng)建動(dòng)態(tài)查詢語句中的條件語句,包括以下步驟:
[0020](311)判斷所述的接口方法的實(shí)際傳遞參數(shù)值是否為空值,如果是,則繼續(xù)步驟
(312),否則繼續(xù)步驟(315);
[0021](312)判斷該實(shí)際傳遞參數(shù)是否有默認(rèn)值,如果是,則繼續(xù)步驟(313),否則繼續(xù)步驟(314);
[0022](313)將該默認(rèn)值的條件加入到動(dòng)態(tài)查詢語句中的條件語句中;
[0023](314)將該實(shí)際傳遞參數(shù)對(duì)應(yīng)的查詢條件忽略;
[0024](315)判斷該接口方法中是否有該實(shí)際傳遞參數(shù)的動(dòng)態(tài)注解定義,如果是,則繼續(xù)步驟(316);
[0025](316)將該接口方法的條件加入到動(dòng)態(tài)查詢語句中的條件語句中。
[0026]更佳地,所述的步驟(31)和(4)之間,還包括以下步驟:
[0027](32)所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法中定義的JPA查詢結(jié)果返回類型創(chuàng)建動(dòng)態(tài)查詢語句中的選擇部分。
[0028]更進(jìn)一步地,所述的動(dòng)態(tài)JPA查詢類將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的返回對(duì)象,具體為:
[0029]所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法中定義的JPA查詢結(jié)果返回類型將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的POJO對(duì)象。
[0030]更佳地,所述的步驟(31)和(4)之間,還包括以下步驟:
[0031](33)所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法定義中是否有Pageable或Sort類型的參數(shù)以及對(duì)應(yīng)的實(shí)際傳遞參數(shù)值是否為空對(duì)動(dòng)態(tài)查詢語句中的條件語句進(jìn)行排序。
[0032]采用了該發(fā)明中的Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,具有如下有益效果:
[0033]通過使用Spring data的動(dòng)態(tài)查詢擴(kuò)展,在進(jìn)行頁面查詢時(shí),只需要對(duì)查詢結(jié)果的VO類、查詢條件的VO類進(jìn)行一些必要的注解,再在接口中進(jìn)行方法的聲明就可以了。如果以后頁面查詢的需求發(fā)生變化,無論是查詢條件、排序條件或者返回結(jié)果發(fā)生變化,只需要在相應(yīng)的VO類中增加或者修改屬性、注解即可。大大減輕了開發(fā)人員的負(fù)擔(dān),降低了進(jìn)行頁面查詢開發(fā)出錯(cuò)的可能性,增強(qiáng)了軟件的維護(hù)性,提高了軟件開發(fā)的生產(chǎn)力。同時(shí)也增強(qiáng)了代碼的可閱讀性、可理解性(因?yàn)闆]有復(fù)雜的邏輯),具有更廣泛的應(yīng)用范圍。
【專利附圖】
【附圖說明】
[0034]圖1為本發(fā)明的Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法的流程圖。
[0035]圖2為本發(fā)明的Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法應(yīng)用于實(shí)施例的詳細(xì)流程圖。
【具體實(shí)施方式】
[0036]為了能夠更清楚地描述本發(fā)明的技術(shù)內(nèi)容,下面結(jié)合具體實(shí)施例來進(jìn)行進(jìn)一步的描述。
[0037]本技術(shù)是對(duì)Spring data JPA技術(shù)的擴(kuò)展,使其能夠根據(jù)傳遞查詢參數(shù)和返回對(duì)象的特性動(dòng)態(tài)構(gòu)造查詢語句,并動(dòng)態(tài)返回POJO (plain old java object,簡(jiǎn)單的Java對(duì)象)對(duì)象集合。
[0038]本技術(shù)主要就是為了解決在Web開發(fā)中常見的頁面查詢問題,對(duì)Spring data的框架進(jìn)行了擴(kuò)展,使其可以根據(jù)查詢參數(shù)以及返回對(duì)象的特性動(dòng)態(tài)構(gòu)造查詢語句,并且將查詢到的數(shù)據(jù)動(dòng)態(tài)地封裝到返回結(jié)果對(duì)象中。該技術(shù)完美地融合到Spring data框架中,同樣只需要進(jìn)行接口方法定義聲明,而不需要進(jìn)行任何實(shí)際編碼邏輯的實(shí)現(xiàn)。
[0039]Spring data JPA之所以能夠做到只需要進(jìn)行接口聲明而不需要寫任何邏輯代碼,是使用了 Spring的FactoryBean技術(shù),對(duì)接口的調(diào)用動(dòng)態(tài)生成代理類,在代理類中根據(jù)接口中的注解進(jìn)行解析、轉(zhuǎn)換,最終將請(qǐng)求轉(zhuǎn)發(fā)給JPA框架。
[0040]如圖1所示,要使Spring data能夠進(jìn)行動(dòng)態(tài)查詢,首先需要對(duì)JPARepositoryFactoryBean類進(jìn)行擴(kuò)展。當(dāng)調(diào)用定義的接口方法時(shí),擴(kuò)展的FactoryBean類首先創(chuàng)建一個(gè)DelegeatedQueryLookupStrategy實(shí)例(動(dòng)態(tài)查詢確認(rèn)類)。該實(shí)例首先判斷接口方法是否需要進(jìn)行動(dòng)態(tài)查詢,如果不是動(dòng)態(tài)查詢的方法,則由原來的Spring data框架來進(jìn)行處理;如果是動(dòng)態(tài)查詢方法,則創(chuàng)建一個(gè)DynamicJPAQuery對(duì)象實(shí)例(動(dòng)態(tài)JPA查詢類),由該實(shí)例來完成動(dòng)態(tài)創(chuàng)建SQL語句(動(dòng)態(tài)查詢語句)并將JPA的查詢結(jié)果轉(zhuǎn)換成指定的P0J0類對(duì)象。
[0041]判斷一個(gè)接口方法是否是動(dòng)態(tài)查詢也很簡(jiǎn)單,就看該方法是否進(jìn)行了 @DynamicQuery的注解(Annonation)。DynamicJPAQuery類會(huì)根據(jù)接口方法中的參數(shù)定義以及進(jìn)行方法調(diào)用的實(shí)際傳遞參數(shù)值進(jìn)行SQL語句中的條件語句的動(dòng)態(tài)創(chuàng)建。如果傳遞的實(shí)際參數(shù)值不為null,并且方法中有該參數(shù)的動(dòng)態(tài)注解定義,就將該條件加入到查詢語句中(如果該參數(shù)在方法定義中沒有動(dòng)態(tài)注解定義,則表示該參數(shù)不參與SQL語句的構(gòu)建,該參數(shù)值會(huì)被忽略掉)。如果傳遞的值為null,則看該參數(shù)的動(dòng)態(tài)注解是否有默認(rèn)值,如果有默認(rèn)值,則將默認(rèn)值的條件加入到查詢語句中,否則則將該參數(shù)對(duì)應(yīng)的查詢條件忽略掉。
[0042]如果方法接口中定義的返回類型不是JPA的entity類型,則可以根據(jù)返回類型的類注解定義動(dòng)態(tài)構(gòu)建SQL語句中的select部分,并且可以支持比較復(fù)雜的統(tǒng)計(jì)語句和子查詢語句。[0043]另外DynamicJPAQuery還能夠動(dòng)態(tài)地構(gòu)建查詢語句中的排序功能,主要是根據(jù)方法定義中是否有Pageable或者Sort類型的參數(shù)以及傳遞的實(shí)際參數(shù)是否為空來進(jìn)行動(dòng)態(tài)構(gòu)建。
[0044]該擴(kuò)展因?yàn)橥耆赟pring data JPA的框架下進(jìn)行開發(fā)的,因此與該框架的融合非常緊密,完全支持Spring data JPA的高級(jí)特性,例如可以使用query hint來使動(dòng)態(tài)查詢支持cache、transaction等特性。
[0045]我們?cè)趯?shí)現(xiàn)時(shí)還采用了約定優(yōu)于配置(convention over configuration)的軟件開發(fā)方法。該方法也稱作按約定編程,是一種軟件設(shè)計(jì)范式,旨在減少軟件開發(fā)人員需做決定的數(shù)量,獲得簡(jiǎn)單的好處,而又不失靈活性。例如我們會(huì)根據(jù)接口定義的返回值類型來進(jìn)行一系列的約定開發(fā)。
[0046]如果返回的實(shí)體類(entity),則使用JPA Query方法進(jìn)行調(diào)用,如果返回的是一個(gè)自定義的VO類,則使用JPA native Query (本地查詢)來進(jìn)行查詢。
[0047]如果返回類型是List〈?>類型,則只是簡(jiǎn)單將返回結(jié)果轉(zhuǎn)換為一個(gè)列表。
[0048]如果返回的類型是Page〈?>類型,則表示客戶既關(guān)心查詢結(jié)果,又關(guān)心查詢數(shù)量,即我們通常意義上所說的分頁查詢??蚣軙?huì)自動(dòng)構(gòu)建查詢總數(shù)的SQL語句,并且將查詢的總數(shù)信息封裝到Page對(duì)象中。但是同時(shí)也要求在參數(shù)列表中需要有Pagable類型的參數(shù)。
[0049]如圖2所示,下面是本發(fā)明的方法在具體實(shí)施例中的應(yīng)用。
[0050]1、Spring 配置:
[0051]<JPA: repositories base-package= " com.certus.da0.hibernate,query, sample " factory-`class= " com.certus.da0.hibernate, spring.QueryRepositoryFactoryBean" />
[0052]其中的QueryRepositoryFactoryBean 是對(duì)于 Spring factoryBean 類進(jìn)行的擴(kuò)展,使其能對(duì)定義動(dòng)態(tài)查詢的DAO接口進(jìn)行攔截
[0053]2、定義查詢結(jié)果V0:
[0054]
【權(quán)利要求】
1.一種Spring data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的方法包括以下步驟: (1)采用基于SpringFactoryBean創(chuàng)建的動(dòng)態(tài)查詢確認(rèn)類判斷被調(diào)用的接口方法是否需要進(jìn)行動(dòng)態(tài)查詢,如果是,則繼續(xù)步驟(3),否則,繼續(xù)步驟(2); (2)采用原Springdata框架處理該被調(diào)用的接口方法,然后結(jié)束退出; (3)采用基于SpringFactoryBean創(chuàng)建的動(dòng)態(tài)JPA查詢類創(chuàng)建動(dòng)態(tài)查詢語句; (4)所述的動(dòng)態(tài)JPA查詢類將所述的動(dòng)態(tài)查詢語句發(fā)送至JPA框架; (5)所述的動(dòng)態(tài)JPA查詢類將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的返回對(duì)象。
2.根據(jù)權(quán)利要求1所述的Springdata JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的判斷被調(diào)用的接口方法是否需要進(jìn)行動(dòng)態(tài)查詢,具體為: 判斷被調(diào)用的接口方法是否進(jìn)行了動(dòng)態(tài)JPA查詢類的注解。
3.根據(jù)權(quán)利要求1所述的Springdata JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的動(dòng)態(tài)JPA查詢類創(chuàng)建動(dòng)態(tài)查詢語句,具體為: (31)所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法中的參數(shù)定義以及進(jìn)行接口方法調(diào)用的實(shí)際傳遞參數(shù)值創(chuàng)建動(dòng)態(tài)查詢語句中的條件語句。
4.根據(jù)權(quán)利要求3所述的Springdata JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的根據(jù)接口方法中的參數(shù)定義以及進(jìn)行接口方法調(diào)用的實(shí)際傳遞參數(shù)值創(chuàng)建動(dòng)態(tài)查詢語句中的條件語句,包括以下步驟: (311)判斷所述的接口方法的實(shí)際傳遞參數(shù)值是否為空值,如果是,則繼續(xù)步驟(312),否則繼續(xù)步驟(315); (312)判斷該實(shí)際傳遞參數(shù)是否有默認(rèn)值,如果是,則繼續(xù)步驟(313),否則繼續(xù)步驟(314); (313)將該默認(rèn)值的條件加入到動(dòng)態(tài)查詢語句中的條件語句中; (314)將該實(shí)際傳遞參數(shù)對(duì)應(yīng)的查詢條件忽略; (315)判斷該接口方法中是否有該實(shí)際傳遞參數(shù)的動(dòng)態(tài)注解定義,如果是,則繼續(xù)步驟(316); (316)將該接口方法的條件加入到動(dòng)態(tài)查詢語句中的條件語句中。
5.根據(jù)權(quán)利要求3所述的Springdata JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的步驟(31)和(4)之間,還包括以下步驟: (32)所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法中定義的JPA查詢結(jié)果返回類型創(chuàng)建動(dòng)態(tài)查詢語句中的選擇部分。
6.根據(jù)權(quán)利要求5所述的Springdata JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的動(dòng)態(tài)JPA查詢類將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的返回對(duì)象,具體為: 所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法中定義的JPA查詢結(jié)果返回類型將JPA框架的查詢結(jié)果轉(zhuǎn)換成指定類型的POJO對(duì)象。
7.根據(jù)權(quán)利要求3所述的Springdata JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的方法,其特征在于,所述的步驟(31)和(4)之間,還包括以下步驟: (33)所述的動(dòng)態(tài)JPA查詢類根據(jù)接口方法定義中是否有Pageable或Sort類型的參數(shù)以及對(duì)應(yīng)的實(shí)際傳遞參數(shù)值是否為空對(duì)動(dòng)態(tài)查詢語句中的條件語句進(jìn)行排序。
【文檔編號(hào)】G06F17/30GK103870555SQ201410077357
【公開日】2014年6月18日 申請(qǐng)日期:2014年3月4日 優(yōu)先權(quán)日:2014年3月4日
【發(fā)明者】逯利軍, 錢培專, 汪金忠, 林強(qiáng), 李克民, 宋聚平, 盧天華 申請(qǐng)人:賽特斯信息科技股份有限公司