velocity 之 分页查询

谈到velocity 不得不谈freemarker,freemarker的宏是一个好东东,JSP中很多类似的代码(参数不同而已,有可能只是遍历List的数据不同,href或者onclick事件不同),那么freemarker很拿手。velocity相对freemarker的宏就显得很逊色。

喜欢上velocity 是因为他的简洁,方便。语法与freemarker及其相像。拿工作中的分页查询来说。velocity好像也有宏,没用过velocity的宏。但是可以实现宏一样的效果,放在Map里也是可以动态实现的参数的。

首先我的jsp放一个div专业存储数据和分页信息。

<div id="content"></div>

 页面就写一个这样的div即可。

刚进页面应该是默认显示第一页,so onload的时候就应该加载第一页数据。

function page(clickpage, g) { 
            var pageNo = (g == 'forward') ? clickpage- 1 : (g == "next") ? clickpage+ 1 : clickpage;
            // 请求后台 传递pageNo参数,传递htmlData
            document.getElementById("content").innerHTML = htmlDate;
            window.location.href = url;
        }

 注意onload = "page(1,null)"

Action的方法处理大致如下:

String out = ""; // 要输出的HTML
String pageNo = HttpUtil.getAsString(request, "pageNo");   
int pagesize =  16; // 每页显示16条数据
Matcher isNum = Pattern.compile("[0-9]*").matcher(pageNo);//整数正则
int currentpage = !isNum.matches()?1:pageNo.length()>9?1:Integer.parseInt(pageNo);
 int  allcount =  sv.getXXCount();数据库中查询的所有行数;
if(currentpage<1){currentpage = 1;}
int allpage  = allcount/pagesize==0?allcount/pagesize:allcount/pagesize+1;
if(currentpage*pagesize>allcount){
	currentpage = allpage;// 最后一页
}
int start = (currentpage-1)*16+1;// 起始值为前几页+1
int currentpagesize = 0;
if(allcount<=pagesize){
	currentpagesize = allcount;
}else{
	  currentpagesize = start+pagesize<allcount?pagesize:allcount%pagesize;
}
	             
IXXXValue[]  values =  sv.getXXXValues(start,pagesize,currentpage,currentpagesize);
Map retMap = getCacheData(values);
List countList = new ArrayList();
 int startpage = currentpage<10?1:currentpage-5;
int end = startpage + 10;
 if(end>allpage)end = allpage;
	for (int i = startpage; i <= end; i++) {
		countList.add(i);
}
retMap.put("allcount", allcount);
retMap.put("currentpage", currentpage); 
retMap.put("allpage", allpage);
retMap.put("countList", countList);
retMap.put("currentpagesize", currentpagesize);
out = VelocityHelper.evaluateTemplate(retMap, "vm/XXXPage.vm");
				

 

out就是我们要得到的HTML数据,看getCacheData(ivalues) 方法主要是把查询的数据对象放入Map中,然后把所有的Map存储到ArrayList中:

public static Map getCacheData(IXXXValues[] values) throws Exception {			
List dataList = new ArrayList();
   if(values != null){
   for(int i=0; i<values.length; i++){
       Map tmpMap = new HashMap();
			tmpMap.put("col1", values[i].getXXX());
			tmpMap.put("col2", values[i].getYYY());
			dataList.add(tmpMap);
     }
    }
    Map retMap = new HashMap();
    retMap.put("dataList", dataList);
    return retMap ;
}

 然后我们看evaluateTemplate方法:

	public static String evaluateTemplate(Map context, String filepath) throws Exception {
		try{
			Template template = Velocity.getTemplate(filepath, "GBK");
			Writer writer = new StringWriter();
			VelocityContext vContext = new VelocityContext(context);
			template.merge(vContext, writer);
			return writer.toString();
		}catch (Exception ex) {
			ex.printStackTrace();
			throw new Exception(ex);
		} 
	}

 XXX.vm是我们的模板内容,主要的有:

#if ($dataList.size()>0) 
	<table>
		#foreach($datalistOne in $dataList)
			<tr class="">
		        	<td>	
                                     #if($datalistOne.notes.length()>=3)	        
                                               #if($!$datalistOne.notes)								        	
                                                     $datalistOne.notes.substring(0,3)
						     #else
                                                          
						#end
						#else
							$datalistOne.notes
					 #end 	
		        	</td>
		    </tr>
		#end
	</table>
	<div>
		   #if ($currentpage==1) 
	                <span class="front" style = "background-color:yellow;">上一页</span>  
	                #else  
	                    <a href = "#" onclick = "page($currentpage,'forward')">上一页</a>  
	            #end
		   #foreach( $something in $countList)
			#if ($something== $currentpage)  
                             <span class="current" style = "background-color:red;">$something</span>  
                             #else  
                              <a href = "#" onclick = "page($something,'144');">$something</a>  
	                #end
		    #end	
		     #if ($currentpage==$allpage) 
	                <span class="front" style = "background-color:yellow;">下一页</span>  
	                 #else  
	                    <a href = "#" onclick = "page($currentpage,'next')">下一页</a>  
	             #end
		     当前页$currentpage
		     总页数  $allpage
		     当前页条数 $currentpagesize
	</div>
	#else
		没有查询到相关数据
#end

 主要是功能,界面比较难看,分页模仿百度的分页效果,可以对页码进行分页,自动前进后退。

 

因为每次请求都替换了content ,所以不需要跳转页面。

在vm中开始用了javascript:void(0); 最开始时用页面跳转做的,分页的时候window.location.href无效了。

IE的一个傻逼哄哄的BUG引起window.location.href 跳转失败,被其他代码干扰,(例如void(0)、return false ),导致找不到父框架,解决办法后加一句window.event.returnValue = false;在AJAX盛行的今天,当在返回success状态(200)后特别容易出问题,避免刷新页面用void(0)。

 

遇到一个非常奇怪的问题,在三元表达式中web app和直接main()入口写执行结果不一样,看来() 非常重要,更加有可读性,在稍微复杂一点的三元运算中不管是为了可读性,还是为了少出现bug,最好在计算中都加上()。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(velocity)