唐 煒
(隴東學(xué)院 信息中心,甘肅 慶陽 745000)
Spring Data、MongoDB、Thymeleaf的數(shù)據(jù)持久化方案及分頁技術(shù)實現(xiàn)
唐 煒
(隴東學(xué)院 信息中心,甘肅 慶陽 745000)
數(shù)據(jù)持久化是大多數(shù)軟件系統(tǒng)業(yè)務(wù)部分的核心,軟件開發(fā)者對于開發(fā)框架的選擇其數(shù)據(jù)持久化部分的影響顯得非常重要,Spring Data已經(jīng)發(fā)展了一段時間了,但是隨著其不斷地更新,其功能變得越來越復(fù)雜和強大。借助于Spring Boot創(chuàng)建一個軟件開發(fā)環(huán)境,整合Spring Data,以Spring Data實現(xiàn)數(shù)據(jù)持久化工作,采用MongoDB為數(shù)據(jù)庫,并通過Spring Data提供的接口API訪問數(shù)據(jù)并實現(xiàn)數(shù)據(jù)分頁,最后數(shù)據(jù)展示通過Thymeleaf和Spring的整合實現(xiàn)。Thymeleaf模板技術(shù)是一種相對比較新的技術(shù),較之前的Freemaker和Velocity模板技術(shù)是有了很大進步,目前這方面的文獻資料比較少。
Spring Data;Thymeleaf;MongoDB;數(shù)據(jù)分頁
Abstract: Data persistence is the core of most software system.The developers’ choice of development framework is impacted by the part of data persistence.Spring Data has been developing for some time,but as it continues to update,the function becomes more and more complex and powerful.In this paper,by using Spring Boot,we aim to build a development environment and integrate Spring Data and MongoDB database,and then implement data persistence and data paging.Research Spring Data is very important to the developers who develop software based on Spring Framework.Thymeleaf template‘s technology is revolution for Free maker and Velocity template’s technology.Presently there are few literatures in this field.
Keywords: Spring Data;Thymeleaf;MongoDB;data paging
Spring(2010)[1,8]是目前JAVA軟件工程里面最流行的企業(yè)級開發(fā)框架[2],Spring Data(2016)[3,9]是Spring的核心項目之一,其目的是實現(xiàn)統(tǒng)一標(biāo)準(zhǔn)的數(shù)據(jù)持久化技術(shù),開發(fā)人員在面對各種數(shù)據(jù)持久化技術(shù)例如關(guān)系數(shù)據(jù)庫和NoSQL(2010)[4]數(shù)據(jù)庫、Oracle和Mysql時,其CRUD操作是一致的,使得軟件工程中DAO層操作統(tǒng)一,開發(fā)者不用關(guān)心具體的數(shù)據(jù)庫技術(shù),集中精力在軟件開發(fā)的業(yè)務(wù)模型上,Spring Data不僅提供了統(tǒng)一的JPA操作,同時也提供了Map-reduce操作。圖1中描述了Spring Data整個體系。雖然Spring Data提供了諸如PagingAndSortingRepository這樣的接口,開發(fā)者利用這樣的接口傳遞Pageable參數(shù)實現(xiàn)分頁,但是要實現(xiàn)數(shù)據(jù)分頁,我們的程序還是需要做一定的工作,目前最常見的是直接利用Pageable作為查詢條件參數(shù)實現(xiàn)分頁,這樣里面會存在一些問題,例如:每次需要傳遞數(shù)據(jù)頁碼,并對參數(shù)進行一定的處理,一些文獻中提出了分頁實現(xiàn)的解決方案但是沒有說清楚這種處理方式[5-6]。本文不僅詳細(xì)解釋實現(xiàn)了數(shù)據(jù)分頁,同時對參數(shù)處理進行了一些特別的處理,同時利用Thymeleaf[8]技術(shù)實現(xiàn)分頁模塊化定制,開發(fā)人員可以利用Thymeleaf中的fragment在任何地方調(diào)用自己定義的不同的分頁片段。
圖1 Spring Data體系
1.1SpringData
Spring Data實現(xiàn)了倉庫存儲對象映射為自定義對象,這一點上Spring Data與Hibernate有點類似,只不過Spring Data不需要在每個對象屬性里面詳細(xì)描述映射到倉庫中對應(yīng)的字段。Spring Data利用在Repository中使用屬性名實現(xiàn)條件查詢,例如要查詢所有記錄Repository接口中需要編寫findAll()方法,但是不需要寫具體的實現(xiàn),Spring Data會自動構(gòu)建實現(xiàn)方法。如果Domain有name屬性,那么查詢條件為name的所有記錄方法應(yīng)該寫成findByName(String name);可以通過xml文件或者JavaConfig集成Spring Data到項目中。
1.2MongoDB
MongoDB[11]是一種NoSQL數(shù)據(jù)庫,基于分布式文件存儲的數(shù)據(jù)庫,MonogDB目前已經(jīng)運用于工業(yè)環(huán)境中,自大數(shù)據(jù)時代以來,存儲系統(tǒng)橫向擴展以及高性能的要求使得關(guān)系數(shù)據(jù)庫的歷史地位正在被非關(guān)系數(shù)據(jù)庫取代。非關(guān)系數(shù)據(jù)的流行對軟件開發(fā)者提出了新的要求,原來基于關(guān)系數(shù)據(jù)庫的設(shè)計思路不能很好地體現(xiàn)非關(guān)系數(shù)據(jù)庫的優(yōu)點。
1.3Thymeleaf
Thymeleaf是目前Java Web開發(fā)最先進的模板技術(shù),相比較其他模板技術(shù)例如Freemaker、Velocity[11],Thymeleaf使得HTML里面嵌入Thymeleaf的代碼不會影響HTML原來的表現(xiàn),HTML代碼也不會干擾Thymeleaf在程運行時的表現(xiàn),Spring Framework已經(jīng)集成了Thymeleaf,開發(fā)基于Spring Framework的軟件系統(tǒng),利用Thymeleaf將會極大地提高開發(fā)速度,同時完美地實現(xiàn)頁面渲染,利用Thymeleaf模板技術(shù)可以解決在不同的開發(fā)環(huán)境例如Windows系統(tǒng)和linux系統(tǒng)、IntellijIdea和Eclipse時與程序運行不同環(huán)境時資源文件路徑的問題。
我們設(shè)計了一個簡單的軟件系統(tǒng),它符合MVC的設(shè)計思路,同時在架構(gòu)方面也符合Restful的SOA要求,軟件系統(tǒng)包含了Controller層、Service層、Repository、Domain,業(yè)務(wù)邏輯方面通過Controller控制系統(tǒng)運行,同時實現(xiàn)Restful的Web Service,在Controller里面調(diào)用Service方法,Service方法通過Repository實現(xiàn)對數(shù)據(jù)的控制。運行流程如圖2所示:
圖2 系統(tǒng)運行流程圖
3.1工程項目中引入SpringData
引入MongoDB作為數(shù)據(jù)持久化的方案,MongoDB已經(jīng)是現(xiàn)在最流行的NoSQL數(shù)據(jù)庫。
3.2Repository接口
項目中的Repository繼承Spring Data的Repository接口,Spring Data提供的
Repository接口比較多,本文繼承了PagingAndSortingRepository接口。
BaseRepository.java:
import org.springframework.data.repository.PagingAndSortingRepository;
public interface BaseRepository
PagingAndSortingRepository
T findById(ID id);
}
DemoRepository.java:
public interface DemoRepository extends BaseRepository
}
3.3Service層
Service層編寫了一個統(tǒng)一接口BaseService.java:
public interface BaseService Page } BaseServiceImpl.java: public class BaseServiceImpl @Autowired private JPA jpa; public Page return this.jpa.findAll(pageable); } } DemoService.java: public interface DemoService extends BaseService } DemoServiceImpl.java: @Service public class DemoServiceImpl extends BaseServiceImpl @Autowired(required=true) private DemoRepository repository; public Demo findById(String id){ return this.repository.findOne(id); } } 查詢所有數(shù)據(jù)可以在Service層中調(diào)用findAll(Pageable pageable)方法。 3.4Controller層 Controller里面不僅實現(xiàn)了對數(shù)據(jù)分頁查詢,而且同時也實現(xiàn)了自定義排序。 @Controller public class DemoController { @Autowired private DemoService demoService; @RequestMapping(value="/**",method=RequestMethod.GET) public ModelAndView get(Model model,Pageable pageable) { ModelAndView mv=new ModelAndView(“demo”); Sort sort=new Sort(Sort.Direction.DESC,“demo”); Pageable p=new PageRequest(pageable.getPageNumber(),5,sort); PageWrapper (this.demoService.findAll(p),"/demo"); model.addAttribute(“page”,page); return mv; } } 3.5Utils:PageWrapper.java 為了更好地實現(xiàn)分頁功能,需要編寫一個PageWrapper.java實現(xiàn)對分頁對象的封裝。 public class PageWrapper public static final int MAX_PAGE_ITEM_DISPLAY=10; private Page private List private int currentNumber; private String url; public String getUrl(){ return url; } public void setUrl(String url){ this.url=url; } public PageWrapper(Page this.page=page; this.url=url; items=new ArrayList currentNumber=page.getNumber()+ 1;//start from 1 to match page.page int start,size; if(page.getTotalPages()<=MAX_PAGE_ITEM_DISPLAY){ start=1; size=page.getTotalPages(); } else { if(currentNumber <=MAX_PAGE_ITEM_DISPLAY - MAX_PAGE_ITEM_DISPLAY/2){ start=1; size=MAX_PAGE_ITEM_DISPLAY; } else if(currentNumber >=page.getTotalPages()- MAX_PAGE_ITEM_DISPLAY/2){ start=page.getTotalPages()- MAX_PAGE_ITEM_DISPLAY + 1; size=MAX_PAGE_ITEM_DISPLAY; } else { start=currentNumber - MAX_PAGE_ITEM_DISPLAY/2; size=MAX_PAGE_ITEM_DISPLAY; } } for(int i=0;i items.add(new PageItem(start+i,(start+i)==currentNumber)); } } public List return items; } public int getNumber(){ return currentNumber; } public List return page.getContent(); } public int getSize(){ return page.getSize(); } public int getTotalPages(){ return page.getTotalPages(); } public boolean isFirstPage(){ return page.isFirst(); } public boolean isLastPage(){ return page.isLast(); } public boolean isHasPreviousPage(){ return page.hasPrevious(); } public boolean isHasNextPage(){ return page.hasNext(); } public class PageItem { private int number; private boolean current; public PageItem(int number,boolean current){ this.number=number; this.current=current; } public int getNumber(){ return this.number; } public boolean isCurrent(){ return this.current; } } } 3.6View層 利用Thymeleaf實現(xiàn)數(shù)據(jù)展示,創(chuàng)建一個專用的page.html fragement以后可以在任何地方調(diào)用分頁導(dǎo)航。 page.html:
需要在demo.html 文件中調(diào)用page.html中分頁導(dǎo)航部分:
3.7運行
程序運行結(jié)果與我們期望的是一樣的,這里需要注意url有些變化,DemoController.java里面處理的RequestMapping是沒有后面的參數(shù)的,系統(tǒng)之所以能實現(xiàn)參數(shù)處理,我們需要對Spring的HandlerMethodArgumentResolver進行處理,在DemoApplication里面需要加入以下方法:
public void addArgumentResolvers(List
PageableHandlerMethodArgumentResolver resolver= new PageableHandlerMethodArgumentResolver();
resolver.setFallbackPageable(new PageRequest(1,15));
argumentResolvers.add(resolver);
}.運行結(jié)果:
圖2 工程項目的運行結(jié)果
Spring Data是一種JPA操作的統(tǒng)一形式,如果軟件設(shè)計合理,幾乎不需要額外的數(shù)據(jù)庫查詢語句就能實現(xiàn)數(shù)據(jù)持久化管理。本文利用Spring Data實現(xiàn)了數(shù)據(jù)查詢和分頁技術(shù),后臺數(shù)據(jù)持久化技術(shù)采用MongoDB,既是Spring Data的研究,也是對MongoDB使用的研究,在前端展示使用了目前最先進的模板技術(shù)。Thymeleaf,Thymeleaf的易用性和強大的功能使得其必將取代Freemaker、Velocity等模板技術(shù),利用Thymeleaf的fragment技術(shù)可以很好地將通用代碼獨立出來,嵌入到其他軟件工程領(lǐng)域。
[1]Praveen Gupta,M.C.Govil,Spring.Web MVC Framework for rapid open source J2EE application development: a case study[J].International Journal of Engineering Science and Technology,2010,2(6):1684-1689.
[2]張宇,王映輝,張翔南.基于Spring的MVC框架設(shè)計與實現(xiàn)[J].計算機工程,2010,36(4):59-62.
[3]Mark Pollackg,Thomas RisbergOliver,Gierke,etc.http://docs.spring.io/spring-data/ data-mongo/docs/1.8.6.RELEASE/reference/html[EB/OL],2016-09-29/2016-10-05.
[4]Stonebraker M.SQL databases v.NoSQL databases[J].Communications of the Acm,2010,53(4):10-11.
[5]時月梅.基于Spring MVC、MyBatis實現(xiàn)數(shù)據(jù)分頁顯示處理[J].信息與電腦(理論版),2015(10):138-140.
[6]周建韡,羅辛,史有群,等.基于Spring MVC的數(shù)據(jù)庫分頁查詢技術(shù)及應(yīng)用研究[J].智能計算機與應(yīng)用,2014(4):9-12.
[7]Thymeleaf.http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html[EB/OL],2016-10-08/2016-11-28.
[8]Rod Johnson,Juergen Hoeller,Keith Donald,etc.http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle[EB/OL],2016-11-21/2016-11-23.
[9]Konda M.Just Spring Data Access[M].Oreilly Vlg Gmbh & Co,2012:22-26.
[10]陳濤,白栩翔.Velocity模板引擎技術(shù)在Java Web中的應(yīng)用[J].農(nóng)業(yè)網(wǎng)絡(luò)信息,2011(5):38-40.
[11]Elif Dede,Madhusudhan Govindaraju,Daniel Gunter,et al.A Performance Evaluation of a MongoDB and Hadoop Platform for Scientific Data Analysis[C].The Workshop on Scientific Cloud Computing,2013:13-20.
【責(zé)任編輯朱世廣】
ImplementofDataPersistenceSolutionandPagingbySpringData,MongoDBandThymeleaf
TANG Wei
(InformationCenter,LongdongUniversity,Qingyang745000,Gansu)
TP311.5
A
1674-1730(2017)05-0009-05
2016-12-26
唐 煒(1983—),男,甘肅慶陽人,助理工程師,碩士,主要從事計算機軟件開發(fā)及計算機網(wǎng)絡(luò)研究。