Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)

        林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

       摘要:本文实现了一个后台由Spring+Mybatis+SpringMVC组成,分页采用PageHelper,前台展示使用bootstrap-paginator来显示效果的分页实例。整个项目由maven构成。这里主要讲了分页的实例,框架怎么搭建就不再说明,主要是在这里的基础上来增加分页功能的。注意,此文是在这个基础 Spring+Mybatis+SpringMVC+Maven+MySql搭建实例 之上来做分页的,建议文中看不懂的配置可以看看这里。

整个工程下载(旧版本,日志打印使用log4j,数据库配置放在properties文件)

新版本下载:https://github.com/appleappleapple/ssm_project (日志打印使用logback,数据库配置放在POM.XML)博主推荐使用新版本,而且这里详细说明了整个工程应用的框架,数据源配置,SQL语句等等!

重要的事情说三遍:请下新版本~请下新版本~请下新版本~

最后的结果如下:

环境:jdk1.6

         Tomcat 7.0

         Eclipse luna/windows 7    

一、后台PageHelper使用

PageHelper:https://github.com/pagehelper/Mybatis-PageHelper

1、引入jar包

 

		
		
			com.github.pagehelper
			pagehelper
			4.0.0
		


2.mybatis-config.xml中添加插件

 

 


    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

这样子就引入进来了,接下来就是来开始分页功能的实现

 

3、mapper文件中添加如下一个方法:

 

	


注意,这里的返回其实是一个list

 

	
	
		
		
		
		
	


4、然后就是dao类

 

 

	 /**
	  * 
	  * @author linbingwen
	  * @since  2015年10月22日 
	  * @param userName
	  * @return
	  */
	 List selectUserByUserName(@Param("userName") String userName);


这里一定的记得加@Param("userName")

 

接下来就可以在service层中添加分页查询的的接口了

5、接口类

 

	/**
	 * 
	 * @author linbingwen
	 * @since  2015年10月23日 
	 * @param userName 查询条件,可为空
	 * @param pageNo 查询条件,可为空,默认取1
	 * @param pageSize 查询条件,可为空,默认取10
	 * @return
	 */
	PagedResult queryByPage(String userName,Integer pageNo,Integer pageSize);

6、实现类

 

 

	public PagedResult queryByPage(String userName,Integer pageNo,Integer pageSize ) {
		pageNo = pageNo == null?1:pageNo;
		pageSize = pageSize == null?10:pageSize;
		PageHelper.startPage(pageNo,pageSize);  //startPage是告诉拦截器说我要开始分页了。分页参数是这两个。
		return BeanUtil.toPagedResult(userDao.selectUserByUserName(userName));
	}

这里就可以直接在返回里头使用了PageHelper,这里userDao.selectUserByUserName(userName)的返回是一个list

 

其中,PagedResult是我自己封装的一个分页结果类

 

package com.lin.util;

import java.util.List;

import com.lin.dto.BaseEntity;

/**
 * 功能概要:
 * 
 * @author linbingwen
 * @since  2015年10月23日 
 */
public class PagedResult extends BaseEntity {
	
	/*serialVersionUID*/
	private static final long serialVersionUID = 1L;

	private List dataList;//数据
	
	private long pageNo;//当前页
	
	private long pageSize;//条数
	
	private long total;//总条数
	
	private long pages;//总页面数目

	public List getDataList() {
		return dataList;
	}

	public void setDataList(List dataList) {
		this.dataList = dataList;
	}

	public long getPageNo() {
		return pageNo;
	}

	public void setPageNo(long pageNo) {
		this.pageNo = pageNo;
	}

	public long getPageSize() {
		return pageSize;
	}

	public void setPageSize(long pageSize) {
		this.pageSize = pageSize;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public long getPages() {
		return pages;
	}

	public void setPages(long pages) {
		this.pages = pages;
	}
	
}

这是它的基类

 

 

package com.lin.dto;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * 类说明:bean基类
 * 
 * 

* 详细描述: * * @author costin_law * @since 2014-5-5 */ public abstract class BaseEntity implements Serializable{ private static final long serialVersionUID = 1L; private static Map,PropertyInfo[]> class2Props = new HashMap,PropertyInfo[]>(128); @Override public String toString() { PropertyInfo[] props = class2Props.get(this.getClass()); if( props == null ){ props = getProps(this.getClass()); } StringBuilder builder = new StringBuilder(1024); boolean isFirst = true; for (int i = 0, n = props.length; i < n; i++) { try { PropertyInfo propInfo = props[i]; Object value = propInfo.getMethod.invoke(this, new Object[0]); if (isFirst) isFirst = false; else builder.append(","); builder.append(propInfo.propName); builder.append(":"); if (value instanceof String) builder.append("\""); builder.append(value); if (value instanceof String) builder.append("\""); } catch (Exception e) { // ignore } } return "{" + builder.toString() + "}"; } private static PropertyInfo[] getProps(Class clazz) { PropertyInfo[] props; Method[] allMethods = clazz.getMethods(); List propList = new ArrayList(); for (int i = 0, n = allMethods.length; i < n; i++) { try { Method method = allMethods[i]; if ((method.getModifiers() & Modifier.PUBLIC) == 1 && method.getDeclaringClass() != Object.class && (method.getParameterTypes() == null || method .getParameterTypes().length == 0)) { String methodName = method.getName(); if (methodName.startsWith("get") || methodName.startsWith("is") ) { PropertyInfo propInfo = new PropertyInfo(); propInfo.getMethod = method; if (methodName.startsWith("get")) { propInfo.propName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4); } else if (methodName.startsWith("is")) { propInfo.propName = methodName.substring(2, 3).toLowerCase() + methodName.substring(3); } propList.add(propInfo); } } }catch(Exception e){ } } props = new PropertyInfo[propList.size()]; propList.toArray(props); class2Props.put(clazz, props); return props; } static class PropertyInfo{ Method getMethod; String propName; } }

BeanUtil是一个将PageHelper返回的list转成pageResult的工具

package com.lin.util;

import java.util.List;

import com.github.pagehelper.Page;
import com.lin.util.PagedResult;

/**
 * 功能概要:
 * 
 * @author linbingwen
 * @since  2015年10月22日 
 */


public class BeanUtil {

    public static  PagedResult toPagedResult(List datas) {
        PagedResult result = new PagedResult();
        if (datas instanceof Page) {
            Page page = (Page) datas;
            result.setPageNo(page.getPageNum());
            result.setPageSize(page.getPageSize());
            result.setDataList(page.getResult());
            result.setTotal(page.getTotal());
            result.setPages(page.getPages());
        }
        else {
            result.setPageNo(1);
            result.setPageSize(datas.size());
            result.setDataList(datas);
            result.setTotal(datas.size());
        }

        return result;
    }

}


7、这样就好了,可以跑单元测试了

 

 

	/**
	 * 分页测试
	 * @author linbingwen
	 * @since  2015年10月22日
	 */
	@Test
	public void queryByPage(){
		 PagedResult  pagedResult = userService.queryByPage(null,1,10);//null表示查全部	
		 logger.debug("查找结果" + pagedResult);
	}
	


输出结果:

 

Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)_第1张图片
看不清的话看下面
Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)_第2张图片
 

查找结果{total:46,dataList:Page{pageNum=1, pageSize=10, startRow=0, endRow=10, total=46, pages=5, reasonable=false,

 pageSizeZero=true},pageNo:1,pageSize:10,pages:5}

其中的dataList中存放的就是数据

打个断点看下就知道了:

Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)_第3张图片

 

 

二、前台展示分页结果

         前台展示主要使用了bootstrap-paginator,这里的原理其实就是将上面查出来的结果,转换成json数据传给前台,然后前台再根据条数和分页数目、总目生成表格,同时每次点击对应的按钮都发送一个ajax请求到后台查询应对的数据,前台每次发送到后台都会包含分页数目、查询条件

1、Controller层的基类

这个基类主要实现了将数据转成json

引用到的jar包如下:

 


		
			net.sf.json-lib
			json-lib
			2.3
			jdk15
		

		
			org.springframework.data
			spring-data-commons
			1.6.1.RELEASE
		

		
			org.springframework.data
			spring-data-jpa
			1.4.1.RELEASE
		

		
			com.alibaba
			fastjson
			1.1.34
		

基类如下:

 

 

package com.lin.controller;

import com.lin.common.HttpConstants;
import com.lin.json.JsonDateValueProcessor;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * Controller基类
 */
public class BaseController {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    
    protected final static String DATE_FORMATE = "yyyy-MM-dd";
    
    /**
     * 返回服务端处理结果
     * @param obj 服务端输出对象
     * @return 输出处理结果给前段JSON格式数据
     * @author YANGHONGXIA
     * @since 2015-01-06
     */
	public String responseResult(Object obj){
		JSONObject jsonObj = null;
		if(obj != null){
		    logger.info("后端返回对象:{}", obj);
		    JsonConfig jsonConfig = new JsonConfig(); 
		    jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
		    jsonObj = JSONObject.fromObject(obj, jsonConfig);
		    logger.info("后端返回数据:" + jsonObj);
		    if(HttpConstants.SERVICE_RESPONSE_SUCCESS_CODE.equals(jsonObj.getString(HttpConstants.SERVICE_RESPONSE_RESULT_FLAG))){
		    	jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, false);
		    	jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, "");
		    }else{
		    	jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, true);
		    	String errMsg = jsonObj.getString(HttpConstants.SERVICE_RESPONSE_RESULT_MSG);
		    	jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, errMsg==null?HttpConstants.SERVICE_RESPONSE_NULL:errMsg);
		    }
		}
		logger.info("输出结果:{}", jsonObj.toString());
		return jsonObj.toString();
	}
	
	/**
     * 返回成功
     * @param obj 输出对象
     * @return 输出成功的JSON格式数据
     */
	public String responseSuccess(Object obj){
		JSONObject jsonObj = null;
		if(obj != null){
		    logger.info("后端返回对象:{}", obj);
		    JsonConfig jsonConfig = new JsonConfig(); 
		    jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
		    jsonObj = JSONObject.fromObject(obj, jsonConfig);
		    logger.info("后端返回数据:" + jsonObj);
		    jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, false);
		    jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, "");
		}
		logger.info("输出结果:{}", jsonObj.toString());
		return jsonObj.toString();
	}

	/**
	 * 返回成功
	 * @param obj 输出对象
	 * @return 输出成功的JSON格式数据
	 */
	public String responseArraySuccess(Object obj){
		JSONArray jsonObj = null;
		if(obj != null){
			logger.info("后端返回对象:{}", obj);
			JsonConfig jsonConfig = new JsonConfig();
			jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
			jsonObj = JSONArray.fromObject(obj, jsonConfig);
			logger.info("后端返回数据:" + jsonObj);
		}
		logger.info("输出结果:{}", jsonObj.toString());
		return jsonObj.toString();
	}
	
	/**
     * 返回成功
     * @param obj 输出对象
     * @return 输出成功的JSON格式数据
     */
	public String responseSuccess(Object obj, String msg){
		JSONObject jsonObj = null;
		if(obj != null){
		    logger.info("后端返回对象:{}", obj);
		    JsonConfig jsonConfig = new JsonConfig(); 
		    jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
		    jsonObj = JSONObject.fromObject(obj, jsonConfig);
		    logger.info("后端返回数据:" + jsonObj);
		    jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, false);
		    jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, msg);
		}
		logger.info("输出结果:{}", jsonObj.toString());
		return jsonObj.toString();
	}
	
	/**
     * 返回失败
     * @param errorMsg 错误信息
     * @return 输出失败的JSON格式数据
     */
    public String responseFail(String errorMsg){
    	JSONObject jsonObj = new JSONObject();
    	jsonObj.put(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, true);
    	jsonObj.put(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, errorMsg);
        logger.info("输出结果:{}", jsonObj.toString());
        return jsonObj.toString();
    }

}

上面用到的一些变量如下:

 

 

package com.lin.common;

public class HttpConstants {

	public static final String SYSTEM_ERROR_MSG = "系统错误";
	
	public static final String REQUEST_PARAMS_NULL = "请求参数为空";

	public static final String SERVICE_RESPONSE_NULL = "服务端返回结果为空";
	
	// 服务端返回成功的标志
	public static final String SERVICE_RESPONSE_SUCCESS_CODE = "AMS00000";
	
	// 服务端返回结果的标志
	public static final String SERVICE_RESPONSE_RESULT_FLAG = "returnCode";
	
	// 服务端返回结果失败的标志
	public static final String SERVICE_RESPONSE_RESULT_MSG = "errorMsg";
	
	// 返回给前段页面成功或失败的标志
	public static final String RESPONSE_RESULT_FLAG_ISERROR = "isError";
	
	// 执行删除操作
	public static final String OPERATION_TYPE_DELETE = "D";

	public static final String ENUM_PATH = "com.mucfc.msm.enumeration.";
	
}


引用一个包的内容如下:

 

 

package com.lin.json;

import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class JsonDateValueProcessor implements JsonValueProcessor {

    /**
     * datePattern
     */
    private String datePattern = "yyyy-MM-dd HH:mm:ss";

    /**
     * JsonDateValueProcessor
     */
    public JsonDateValueProcessor() {
        super();
    }

    /**
     * @param format
     */
    public JsonDateValueProcessor(String format) {
        super();
        this.datePattern = format;
    }

    /**
     * @param value
     * @param jsonConfig
     * @return Object
     */
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return process(value);
    }

    /**
     * @param key
     * @param value
     * @param jsonConfig
     * @return Object
     */
    public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
        return process(value);
    }

    /**
     * process
     *
     * @param value
     * @return
     */
    private Object process(Object value) {
        try {
            if (value instanceof Date) {
                SimpleDateFormat sdf = new SimpleDateFormat(datePattern, Locale.UK);
                return sdf.format((Date) value);
            }
            return value == null ? "" : value.toString();
        } catch (Exception e) {
            return "";
        }

    }

    /**
     * @return the datePattern
     */
    public String getDatePattern() {
        return datePattern;
    }

    /**
     * @param pDatePattern the datePattern to set
     */
    public void setDatePattern(String pDatePattern) {
        datePattern = pDatePattern;
    }

}

 

这里主要实现了能将list/map/set/数组等转换成josn,并传到前台‘

2、光这里写不行,还得配置springMVC中以json来传递数据,并配置自己的字符过滤器,要不然中文传到前台可能乱码,这里的配置比较复杂,大部分时间都花在这里,

这里我直接放spingMVC的配置:spring-mvc.xml

 



     
    
   
        
        
    
   
   
       
    
        
            
            
                
                
                    
                        
                            
                            
                            
                        
                        
                            
                            
                            
                        
                    
                
            
            
            
                
                    
                        application/json;charset=UTF-8
                    
                
                
                
                
            
        

        
          
        
    


           
    
    
        
        
        
        
        
        
        

         
            
                json=application/json
                xml=application/xml
                html=text/html
            
        
        
        
    



    
      
	
    
   

   
     
      
	




3、Spirng中也和配置:

 

 



           
           	 
    
    
     
       
     
        
            
               classpath:properties/*.properties
                
            
        
    
    
    
    	 
    
        
    
    
    
	
	
	
	
	
 	
    	

	
	
		
		
	   
		
			${jdbc_driverClassName}
		
		
			${jdbc_url}
		
		
			${jdbc_username}
		
		
			${jdbc_password}
		
	

	
	
		
	

    
	
		
          
		
		
	



其中validator这个bean需要引用如下:

 

 


			javax.validation
			validation-api
			1.1.0.Final
		

		
			org.hibernate
			hibernate-validator
			5.0.1.Final
		


4、conroller层编写

 

 

package com.lin.controller;


import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.github.pagehelper.Page;
import com.lin.domain.User;
import com.lin.service.UserService;
import com.lin.util.PagedResult;

/**
 * 功能概要:UserController
 * 
 * @author linbingwen
 * @since  2015年9月28日 
 */
@Controller
public class UserController extends BaseController {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Resource
	private UserService userService;
	
	@RequestMapping("/")  
    public ModelAndView getIndex(){    
		ModelAndView mav = new ModelAndView("index"); 
		User user = userService.selectUserById(1);
	    mav.addObject("user", user); 
        return mav;  
    }  
	
	/**
	 * 显示首页
	 * @author linbingwen
	 * @since  2015年10月23日 
	 * @return
	 */
	@RequestMapping("/bootstrapTest1")  
	public String bootStrapTest1(){
		return "bootstrap/bootstrapTest1";
	}
	
    /**
     * 分页查询用户信息
     * @author linbingwen
     * @since  2015年10月23日 
     * @param page
     * @return
     */
    @RequestMapping(value="/list.do", method= RequestMethod.POST)
    @ResponseBody
    public String list(Integer pageNumber,Integer pageSize ,String userName) {
		logger.info("分页查询用户信息列表请求入参:pageNumber{},pageSize{}", pageNumber,pageSize);
		try {
			PagedResult pageResult = userService.queryByPage(userName, pageNumber,pageSize);
    	    return responseSuccess(pageResult);
    	} catch (Exception e) {
			return responseFail(e.getMessage());
		}
    }
}


5、最后一步就是前台的页面了,这里可以先写页面再来写controller也可以的

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>




Bootstrap分页实例







	
查询用户结果
序号 用户名 密码 用户邮箱

注意引入的js文件,bootstrap-paginator需要引用bootstrap和jquery

 

6、最终运行结果

最后以web工程运行就可以了:

结果如下:

 

打印出来的一些日志:

Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)_第4张图片

后台返回给前台的就是json

整个工程下载(旧版本)

新版本下载:https://github.com/appleappleapple/ssm_project (日志打印使用logback,数据库配置放在POM.XML)博主推荐使用新版本,而且这里详细说明了整个工程应用的框架,数据源配置,SQL语句等等!

重要的事情说三遍:请下新版本~请下新版本~请下新版本~

更多技术请关注笔者微信技术公众号"单例模式"

Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)_第5张图片

你可能感兴趣的:(Spring,SpringMVC,Mybatis)