讓我們從支持分頁的經典JPA方法開始。 考慮一個簡單的域類–一個具有名字,姓氏的“成員”。 為了支持在成員列表上進行分頁,JPA方法是支持一種查找器,該查找器將獲取第一個結果(firstResult)的偏移量和要檢索的結果(maxResults)的大小,方法是:
import java.util.List;import javax.persistence.TypedQuery;import org.springframework.stereotype.Repository;import mvcsample.domain.Member;@Repository
public class JpaMemberDao extends JpaDao<Long, Member> implements MemberDao{public JpaMemberDao(){super(Member.class);}@Overridepublic List<Member> findAll(int firstResult, int maxResults) {TypedQuery<Member> query = this.entityManager.createQuery('select m from Member m', Member.class);return query.setFirstResult(firstResult).setMaxResults(maxResults).getResultList();}@Overridepublic Long countMembers() {TypedQuery<Long> query = this.entityManager.createQuery('select count(m) from Member m', Long.class);return query.getSingleResult();}
}
如上所示,需要一個附加的API返回記錄的數量來確定實體列表的頁數。 使用此API,通常需要用戶界面提供兩個參數:
- 當前顯示的頁面(例如“ page.page”)
- 每頁列表的大小(例如“ page.size”)
控制器將負責通過以下方式將這些輸入轉換為JPA所需的輸入– firstResult和maxResults:
@RequestMapping(produces='text/html')
public String list(@RequestParam(defaultValue='1', value='page.page', required=false) Integer page, @RequestParam(defaultValue='10', value='page.size', required=false) Integer size, Model model){int firstResult = (page==null)?0:(page-1) * size;model.addAttribute('members',this.memberDao.findAll(firstResult, size));float nrOfPages = (float)this.memberDao.countMembers()/size;int maxPages = (int)( ((nrOfPages>(int)nrOfPages) || nrOfPages==0.0)?nrOfPages+1:nrOfPages);model.addAttribute('maxPages', maxPages);return 'members/list';
}
給定一個列表作為模型屬性和所有頁面的數量(上面的maxPages個),可以將該列表轉換為jsp中的一個簡單表,Spring Roo打包了一個不錯的標記庫,可用于顯示在jsp頁面中的分頁元素,我已將其包含在參考中。
因此,這是使用JPA和Spring MVC進行分頁的方法。 Spring-Data-JPA使這個過程變得更加簡單 ,首先是支持檢索分頁列表的存儲庫接口–以最簡單的形式,該存儲庫僅需要擴展Spring-Data-JPA接口,并在運行時生成實現真正JPA調用的代理:
import mvcsample.domain.Member;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;public interface MemberRepository extends JpaRepository<Member, Long>{//
}
鑒于此,訪問存儲庫接口的控制器方法也非常簡單:
@RequestMapping(produces='text/html')
public String list(Pageable pageable, Model model){Page<Member> members = this.memberRepository.findAll(pageable);model.addAttribute('members', members.getContent());float nrOfPages = members.getTotalPages();model.addAttribute('maxPages', nrOfPages);return 'members/list';
}
控制器方法接受一個名為Pageable的參數,此參數使用Spring MVC HandlerMethodArgumentResolver填充,該MVC HandlerMethodArgumentResolver通過名稱“ page.page”和“ page.size”查找請求參數,并將其轉換為Pageable參數。 此自定義HandlerMethodArgumentResolver通過以下方式向Spring MVC注冊:
<mvc:annotation-driven><mvc:argument-resolvers><bean class='org.springframework.data.web.PageableArgumentResolver'></bean></mvc:argument-resolvers>
</mvc:annotation-driven>
JpaRepository API接受pageable參數并返回一個頁面,在內部自動填充也可以從Page方法檢索的頁面數。 如果需要顯式指定查詢,則可以采用多種方法來完成,其中一種方法如下:
@Query(value='select m from Member m', countQuery='select count(m) from Member m')
Page<Member> findMembers(Pageable pageable);
我可以看到的一個問題是,可分頁的頁面號是0索引,而從UI傳遞的那個是1索引,但是PageableArgumentResolver在內部處理并將1索引的UI頁面參數轉換為所需的0索引值。 因此,Spring Data JPA使實現分頁列表頁面變得非常簡單。 我包括一個將所有這些都聯系在一起的示例項目,以及使分頁列表顯示變得簡單的分頁標簽庫。
資源:
- 實現分頁列表的示例項目位于此處 :https://github.com/bijukunjummen/spring-mvc-test-sample.git
- Spring-Data-JPA參考 :http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/
參考資料: all和其他博客中的Spring Data JPA和我們的JCG合作伙伴 Biju Kunjummen的分頁 。
翻譯自: https://www.javacodegeeks.com/2013/01/spring-data-jpa-and-pagination.html