精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-10-01
最后修改:2009-01-16
先看一下效果. 在HTML代码: js框架用的是jQuery. table函数是我自己做的一个表格插件. <#import "/spring.ftl" as spring/> <#import "/shop.ftl" as shop/> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Data Table Demo</title> </head> <body> <script> $(function(){ $('.table4').table({ headers : ['<@spring.message code="profile.detail.title"/>'], data_columns : ['name'], data_key: 'data', data_url : $.root_ctx + '/demo/table3.htm', pageable: true, ajaxPager: true, pageSize: 6 }); }); </script> <div style="width: 90%"> <@shop.panel height=245> <table class="table4" border="0" cellspacing="0" cellpadding="0"></table> </@shop.panel> </div> </body> </html> 再看controller里. @Controller public class DemoController extends BaseController{ private ShopService shopService = null; @Autowired public void setShopService(ShopService shopService) { this.shopService = shopService; } @RequestMapping("/demo/table3.htm") public String testTable3(HttpServletRequest request,ModelMap map) { Object o = doPage(request, map, new PagerExecutor() { @Override public List<?> doInPager(Pager pager) { return shopService.list(); } }); map.addAttribute("data", escapeForJson(o)); return JSON; } } service里的list方法实现 @Override //@Exclude("BaseDao.list") public List<Shop> list() { return shopDao.list(); } dao里的list方法实现 @SuppressWarnings("unchecked") @Override public List<T> list() throws DataAccessException { return getHibernateTemplate().loadAll(clazz); } 到现在. 分页相关的代码已经写完了. 可以看到. service与dao里没有任何与分页有关的代码. 接下来看下实现分页相关的东西. Pager接口 /** * @author Iorn.Gu */ public interface Pager { boolean isEnabled(); void setPageSize(int pageSize); int getPageSize(); void setCurrentPage(int currentPage); int getCurrentPage(); void setFetchCount(boolean fetchCount); PagerResult execute(PagerExecutor executor); } 实现类 public class PagerImpl implements Pager{ private boolean enabled = false; private boolean fetchCount = false; private int pageSize = 10; private int currentPage = 0; private static final Object LOCK = new Object(); @Override public PagerResult execute(PagerExecutor executor) { synchronized (LOCK) { PagerResult result = new PagerResult(); if( fetchCount || currentPage < 0) { enabled = false; List<?> re = executor.doInPager(this); result.setItemCount(re.size()); fetchCount = false; } else if( currentPage != 0 ){ enabled = true; List<?> re = executor.doInPager(this); result.setPageItems(re); enabled = false; } currentPage = 0; return result; } } @Override public void setCurrentPage(int currentPage) { synchronized (LOCK) { if( !isEnabled() ) this.currentPage = currentPage; } } @Override public void setPageSize(int pageSize) { synchronized (LOCK) { if( !isEnabled() ) this.pageSize = pageSize; } } @Override public int getCurrentPage() { return currentPage; } @Override public int getPageSize() { return pageSize; } @Override public boolean isEnabled() { return enabled; } public void setFetchCount(boolean fetchCount) { this.fetchCount = fetchCount; } } PagerResult public class PagerResult { private int itemCount = 0; private List<?> pageItems = null; public int getItemCount() { return itemCount; } public void setItemCount(int itemCount) { this.itemCount = itemCount; } public List<?> getPageItems() { return pageItems; } public void setPageItems(List<?> pageItems) { this.pageItems = pageItems; } } PagerExecutor public interface PagerExecutor { List<?> doInPager(Pager pager); } PageableHibernateTemplete类. 关于PagerMethodExcludeHolder 这个类相关的东西.到最后再说吧.先忽略.! 只看两个prepare方法. public class PageableHibernateTemplete extends HibernateTemplate { private Pager pager = null; private PagerMethodExcludeHolder excludeHolder = null; public PageableHibernateTemplete(SessionFactory sessionFactory) { super(sessionFactory); } @Autowired public void setPager(Pager pager) { this.pager = pager; } @Autowired public void setExcludeHolder(PagerMethodExcludeHolder excludeHolder) { this.excludeHolder = excludeHolder; } @Override protected void prepareCriteria(Criteria criteria) { if( pager.isEnabled() && !isMethodExcluded()) { criteria.setFirstResult((pager.getCurrentPage()-1)*pager.getPageSize()); setMaxResults(pager.getPageSize()); } else { criteria.setFirstResult(0); setMaxResults(0); } super.prepareCriteria(criteria); } @Override protected void prepareQuery(Query queryObject) { if( pager.isEnabled() && !isMethodExcluded() ) { queryObject.setFirstResult((pager.getCurrentPage()-1)*pager.getPageSize()); setMaxResults(pager.getPageSize()); } else { queryObject.setFirstResult(0); setMaxResults(0); } super.prepareQuery(queryObject); } private boolean isMethodExcluded() { String[] excludeds = excludeHolder.getExcludeMethods(); if( excludeds != null ) { StackTraceElement[] elements = (new Throwable()).getStackTrace(); boolean inDao = false; for( StackTraceElement element : elements ) { if( element.getClassName().endsWith("DaoImpl") ) { inDao = true; for( String excluded : excludeds ) { String method = excluded.substring(excluded.lastIndexOf(".")+1); String prefix = excluded.substring(0,excluded.lastIndexOf(".")); if( element.getMethodName().equals(method) && element.getClassName().indexOf(prefix) != -1 ) { System.out.println("exlucde Method:" + element.getClassName() + "." + element.getMethodName()); return true; } } } else if( inDao ){ break; } } } return false; } } 然后是BaseController类的doPager(在上面的controller那块里头用到)方法. @SuppressWarnings("unchecked") protected List<?> doPage(HttpServletRequest request,Map model,PagerExecutor executor) { String getItemCount = request.getParameter("getItemCount"); String currentPage = request.getParameter("currentPage"); String pageSize = request.getParameter("pageSize"); if( "true".equals(getItemCount) ) { pager.setFetchCount(true); PagerResult result = pager.execute(executor); model.put("itemCount", result.getItemCount()); return null; } else if( currentPage != null && !"".equals(currentPage) ) { int curr = Integer.parseInt(currentPage); pager.setCurrentPage(curr); if( pageSize != null && !"".equals(pageSize) ) { int ps = Integer.parseInt(pageSize); pager.setPageSize(ps); } } else { pager.setCurrentPage(-1); } PagerResult result = pager.execute(executor); return result.getPageItems(); } 最后就是那个jQuery的table插件了.. 代码太长. 就只贴取数据那一段了. var AjaxPageableDataModel = function(config){ var param = $.extend({},config.data_param); $.extend(param,{'getItemCount':true}); $.ajax({ async : false, url : config.data_url, data : param, type : 'POST', cache : true, success : function(data){ config.itemCount = eval('('+data+')').itemCount; } }); param['getItemCount'] = false; config.pageCount = parseInt(config.itemCount / config.pageSize); config.pageCount += ((config.itemCount % config.pageSize == 0) ? 0 : 1) return { getData : function(curPage){ config.currentPage = curPage ? curPage : 1; param['currentPage'] = config.currentPage; param['pageSize'] = config.pageSize; var result = false; $.ajax({ async : false, url : config.data_url, data : param, type : 'POST', success : function(data){ result = eval('('+data+')'); } }); return (result && result[config.data_key]) ? result[config.data_key] : []; }, getPageCount : function(){ return config.pageCount; }, getItemCount : function(){ return config.itemCount; } } }; 就这些了. 虽然没写注释,但应该不难看懂. 然后还有PagerMethodExcludeHolder类没有贴.. 这个要说明一下. 因为在service层的方法里. 有可能会调用多个dao的方法. 而dao的方法并不是每一个都要分页处理. 这时就要用到这个类相关的东西了. 在上面的service方法里. 注释了一行@Exclude("BaseDao.list"). 这行表示.BaseDao里的list方法不需要做分页处理. 下面是这些东西的代码. @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Exclude { String[] value() default {}; } @Aspect public class PagerMethodExcludeHolder { private Map<Method, String[]> methodCache = new HashMap<Method, String[]>(); private String[] excludeMethods = null; @Around("execution(public java.util.List *..*service..*.*(..)) and @annotation(com.guyong.common.pager.Exclude)") public Object whenPager(ProceedingJoinPoint joinPoint) throws Throwable { Method method = getCurrentMethod(joinPoint); if( !methodCache.containsKey(method) ) { Exclude exclude = AnnotationUtils.findAnnotation(method, Exclude.class); String[] excludes = null; if( exclude != null ) { excludes = exclude.value(); } methodCache.put(method, excludes); } excludeMethods = methodCache.get(method); Object result = joinPoint.proceed(); excludeMethods = null; return result; } private Method getCurrentMethod(ProceedingJoinPoint joinPoint) { Signature s = joinPoint.getSignature(); Class<?> clazz = joinPoint.getTarget().getClass(); Method getMethod = ReflectionUtils.findMethod(s.getClass(), "getMethod"); ReflectionUtils.makeAccessible(getMethod); Method tmp = (Method)ReflectionUtils.invokeMethod(getMethod, s); Class<?>[] argTypes = tmp.getParameterTypes(); return ReflectionUtils.findMethod(clazz, s.getName(), argTypes); } public String[] getExcludeMethods() { return excludeMethods; } } 好了.. 欢迎大家批评指教. 附件里是效果图跟每页数据的返回值.. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-10-01
看了此贴,我对实现通用分页这件事彻底绝望了
|
|
返回顶楼 | |
发表时间:2008-10-01
繁琐哦。
不过值得一看 |
|
返回顶楼 | |
发表时间:2008-10-01
小弟我实在是技术差实在是看不明白。
|
|
返回顶楼 | |
发表时间:2008-10-02
分页用得上如此多代码?
做软件追求的是复杂问题简单化,简单问题精确化. |
|
返回顶楼 | |
发表时间:2008-10-04
我服了,我也写过分页标签,是实现sql包里的几个接口
简单点,还是用display标签吧 |
|
返回顶楼 | |
发表时间:2008-10-05
没看明白。。。
我的分页就是个查询 多传两个参数 index pageSize。。。 lz用的是springmvc? |
|
返回顶楼 | |
发表时间:2008-10-06
yidwo 写道 分页用得上如此多代码?
做软件追求的是复杂问题简单化,简单问题精确化. 不知道yidwo兄台说的是哪里复杂? 是使用这种分页方式复杂,实现这种分页方式复杂? 或者说哪块的代码多了? 我做这个分页主要要解决的问题是Service的方法里,许多查询方法要重载加上pageSize,currentPage参数. 比如这样: public interface ShopService { List<Shop> list(String name); List<Shop> list(String name,int pageSize,int currentPage); } 如果有什么好的方法,还请多多指教.. laiseeme 写道 没看明白。。。
我的分页就是个查询 多传两个参数 index pageSize。。。 lz用的是springmvc? 恩. 是用的springmvc |
|
返回顶楼 | |
发表时间:2008-10-06
可是从你的这段代码来看
@SuppressWarnings("unchecked") @Override public List<T> list() throws DataAccessException { return getHibernateTemplate().loadAll(clazz); } 似乎是把数据全取出来,然后在内存中分页啊 而且你自己也说了“到现在. 分页相关的代码已经写完了. 可以看到. service与dao里没有任何与分页有关的代码” |
|
返回顶楼 | |
发表时间:2008-10-06
daquan198163 写道 可是从你的这段代码来看
@SuppressWarnings("unchecked") @Override public List<T> list() throws DataAccessException { return getHibernateTemplate().loadAll(clazz); } 似乎是把数据全取出来,然后在内存中分页啊 而且你自己也说了“到现在. 分页相关的代码已经写完了. 可以看到. service与dao里没有任何与分页有关的代码” 并没有取出所有数据. 你仔细看下PageableHibernateTemplete 类. getHibernateTemplate()方法取过来的Template就已经设设置好了maxResults与firstResult. 附件的图里有每次取出来的数据. |
|
返回顶楼 | |