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

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

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

整个工程下载

最后的结果如下:

环境:jdk1.6

Tomcat 7.0

Eclipse luna/windows 7

一、后台PageHelper使用

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

1、引入jar包

		<!-- 添加分布插件的包pagehelper -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.0.0</version>
		</dependency>

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

<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <property name="dialect" value="mysql"/>
        <!-- 该参数默认为false -->
        <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
        <!-- 和startPage中的pageNum效果一样-->
        <property name="offsetAsPageNum" value="true"/>
        <!-- 该参数默认为false -->
        <!-- 设置为true时,使用RowBounds分页会进行count查询 -->
        <property name="rowBoundsWithCount" value="true"/>
        <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
        <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
        <property name="pageSizeZero" value="true"/>
        <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
        <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
        <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
        <property name="reasonable" value="false"/>
        <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
        <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
        <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->
        <!-- 不理解该含义的前提下,不要随便复制该配置 -->
        <property name="params" value="pageNum=start;pageSize=limit;"/>
    </plugin>
</plugins>

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

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

	<select id="selectUserByUserName" parameterType="java.lang.String" resultMap="BaseResultMap">
		SELECT *
		FROM t_user
		WHERE 1 = 1
		<if test="userName != null and userName !=‘‘">
		    AND USER_NAME = #{userName,jdbcType=VARCHAR}
		</if>
		ORDER BY USER_ID
	</select>

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

	<!--设置domain类和数据库中表的字段一一对应,注意数据库字段和domain类中的字段名称不致,此处一定要! -->
	<resultMap id="BaseResultMap" type="com.lin.domain.User">
		<id column="USER_ID" property="userId" jdbcType="INTEGER" />
		<result column="USER_NAME" property="userName" jdbcType="CHAR" />
		<result column="USER_PASSWORD" property="userPassword" jdbcType="CHAR" />
		<result column="USER_EMAIL" property="userEmail" jdbcType="CHAR" />
	</resultMap>

4、然后就是dao类

	 /**
	  *
	  * @author linbingwen
	  * @since  2015年10月22日
	  * @param userName
	  * @return
	  */
	 List<User> 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<User> queryByPage(String userName,Integer pageNo,Integer pageSize);

6、实现类

	public PagedResult<User> 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<T> extends BaseEntity {

	/*serialVersionUID*/
	private static final long serialVersionUID = 1L;

	private List<T> dataList;//数据

	private long pageNo;//当前页

	private long pageSize;//条数

	private long total;//总条数

	private long pages;//总页面数目

	public List<T> getDataList() {
		return dataList;
	}

	public void setDataList(List<T> 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;

/**
 *
 * <b>类说明:</b>bean基类
 *
 * <p>
 * <b>详细描述:</b>
 *
 * @author costin_law
 * @since 2014-5-5
 */
public abstract class BaseEntity implements Serializable{
	private static final long serialVersionUID = 1L;

	private static Map<Class<?>,PropertyInfo[]> class2Props = new HashMap<Class<?>,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<? extends BaseEntity> clazz) {
		PropertyInfo[] props;
		Method[] allMethods = clazz.getMethods();
		List<PropertyInfo> propList = new ArrayList<PropertyInfo>();

		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 <T> PagedResult<T> toPagedResult(List<T> datas) {
        PagedResult<T> result = new PagedResult<T>();
        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<User>  pagedResult = userService.queryByPage(null,1,10);//null表示查全部
		 logger.debug("查找结果" + pagedResult);
	}
	

输出结果:


看不清的话看下面

查找结果{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中存放的就是数据

打个断点看下就知道了:

二、前台展示分页结果

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

1、Controller层的基类

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

引用到的jar包如下:

<!-- 添加json的依赖包 -->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.3</version>
			<classifier>jdk15</classifier>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-commons</artifactId>
			<version>1.6.1.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.4.1.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.1.34</version>
		</dependency>

基类如下:

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <!-- 扫描controller(controller层注入) -->
   <context:component-scan base-package="com.lin.controller" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>

       <!-- 会自动注册了validator  ConversionService  -->
    <mvc:annotation-driven validator="validator" conversion-service="conversionService" content-negotiation-manager="contentNegotiationManager">
        <mvc:message-converters register-defaults="true">
            <!-- StringHttpMessageConverter编码为UTF-8,防止乱码 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
                <property name = "supportedMediaTypes">
                    <list>
                        <bean class="org.springframework.http.MediaType">
                            <constructor-arg index="0" value="text"/>
                            <constructor-arg index="1" value="plain"/>
                            <constructor-arg index="2" value="UTF-8"/>
                        </bean>
                        <bean class="org.springframework.http.MediaType">
                            <constructor-arg index="0" value="*"/>
                            <constructor-arg index="1" value="*"/>
                            <constructor-arg index="2" value="UTF-8"/>
                        </bean>
                    </list>
                </property>
            </bean>
            <!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
            <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
                <!--<property name="serializerFeature">-->
                <!--这个地方加上这个功能吧,能自己配置一些东西,比如时间的格式化,null输出""等等-->
                <!--</property>-->
            </bean>
        </mvc:message-converters>

        <mvc:argument-resolvers>
          <bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

           <!-- 内容协商管理器  -->
    <!--1、首先检查路径扩展名(如my.pdf);2、其次检查Parameter(如my?format=pdf);3、检查Accept Header-->
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
        <property name="favorPathExtension" value="true"/>
        <!-- 用于开启 /userinfo/123?format=json 的支持 -->
        <property name="favorParameter" value="true"/>
        <property name="parameterName" value="format"/>
        <!-- 是否忽略Accept Header -->
        <property name="ignoreAcceptHeader" value="false"/>

        <property name="mediaTypes"> <!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->
            <value>
                json=application/json
                xml=application/xml
                html=text/html
            </value>
        </property>
        <!-- 默认的content type -->
        <property name="defaultContentType" value="text/html"/>
    </bean>

    <!-- 当在web.xml 中   DispatcherServlet使用 <url-pattern>/</url-pattern> 映射时,能映射静态资源 -->
    <mvc:default-servlet-handler />
	<!-- 静态资源映射 -->
    <mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>

   <!-- 对模型视图添加前后缀 -->
     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/view/" p:suffix=".jsp"/>

	<!-- 这里设置静态的资源 -->
<!-- 	<mvc:resources location="/static/" mapping="/static/**" /> -->

</beans>

3、Spirng中也和配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">

           	 <!-- 以下 validator  ConversionService 在使用 mvc:annotation-driven 会 自动注册-->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    </bean>

     <!-- 引入jdbc配置文件 -->
     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
               <value>classpath:properties/*.properties</value>
                <!--要是有多个配置文件,只需在这里继续添加即可 -->
            </list>
        </property>
    </bean>

    	 <!-- 扫描注解Bean -->
    <context:component-scan base-package="com.lin.service">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 激活annotation功能 -->
	<context:annotation-config />
	<!-- 激活annotation功能 -->
	<context:spring-configured />
	<!-- 注解事务配置 -->

 	<!-- 类型转换及数据格式化 -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"/>	

	<!-- 配置数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<!-- 不使用properties来配置 -->
		<!-- <property name="driverClassName" value="com.mysql.jdbc.Driver" />
			<property name="url" value="jdbc:mysql://localhost:3306/learning" />
			<property name="username" value="root" />
			<property name="password" value="[email protected]" /> -->
	   <!-- 使用properties来配置 -->
		<property name="driverClassName">
			<value>${jdbc_driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc_url}</value>
		</property>
		<property name="username">
			<value>${jdbc_username}</value>
		</property>
		<property name="password">
			<value>${jdbc_password}</value>
		</property>
	</bean>

	<!-- 自动扫描了所有的XxxxMapper.xml对应的mapper接口文件,这样就不用一个一个手动配置Mpper的映射了,只要Mapper接口类和Mapper映射文件对应起来就可以了。 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage"
			value="com.lin.dao" />
	</bean>

    <!-- 配置Mybatis的文件 ,mapperLocations配置**Mapper.xml文件位置,configLocation配置mybatis-config文件位置-->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath*:com/lin/mapper/**/*.xml"/>
		<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
		<!-- <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model"
			/> -->
	</bean>

</beans>

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

<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.0.1.Final</version>
		</dependency>

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<User> 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"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bootstrap分页实例</title>
<link href="<%=request.getContextPath()%>/static/js/bootstrap//css/bootstrap.min.css" rel="stylesheet">
<script src="<%=request.getContextPath()%>/static/js/jQuery/jquery-2.1.4.min.js"></script>
<script src="<%=request.getContextPath()%>/static/js/bootstrap/js/bootstrap.min.js"></script>
<script src="<%=request.getContextPath()%>/static/js/bootstrap/js/bootstrap-paginator.min.js"></script>
<style type="text/css">
#queryDiv {
 margin-right: auto;
 margin-left: auto;
 width:600px;
}
#textInput {
 margin-top: 10px;
}
#tableResult {
 margin-right: auto;
 margin-left: auto;
 width:600px;
}
td {
 width:150px
}
</style>
</head>
<body>
	<div id = "queryDiv">
		<input id = "textInput" type="text" placeholder="请输入用户名" >
		<button id = "queryButton" class="btn btn-primary" type="button">查询</button>
	</div>
	<form id="form1">
		<table class="table table-bordered" id = ‘tableResult‘>
			<caption>查询用户结果</caption>
			<thead>
				<tr>
					<th>序号</th>
					<th>用户名</th>
					<th>密码</th>
					<th>用户邮箱</th>
				</tr>
			</thead>
			<tbody id="tableBody">
			</tbody>
		</table>
		<!-- 底部分页按钮 -->
		<div id="bottomTab"></div>
	</form>
	<script type=‘text/javascript‘>
	    var PAGESIZE = 10;
        var options = {
            currentPage: 1,  //当前页数
            totalPages: 10,  //总页数,这里只是暂时的,后头会根据查出来的条件进行更改
            size:"normal",
            alignment:"center",
            itemTexts: function (type, page, current) {
                switch (type) {
                    case "first":
                        return "第一页";
                    case "prev":
                        return "前一页";
                    case "next":
                        return "后一页";
                    case "last":
                        return "最后页";
                    case "page":
                        return  page;
                }
            },
            onPageClicked: function (e, originalEvent, type, page) {
            	var userName = $("#textInput").val(); //取内容
            	buildTable(userName,page,PAGESIZE);//默认每页最多10条
            }
        }  

        //获取当前项目的路径
        var urlRootContext = (function () {
            var strPath = window.document.location.pathname;
            var postPath = strPath.substring(0, strPath.substr(1).indexOf(‘/‘) + 1);
            return postPath;
        })();

        //生成表格
        function buildTable(userName,pageNumber,pageSize) {
        	 var url =  urlRootContext + "/list.do"; //请求的网址
             var reqParams = {‘userName‘:userName, ‘pageNumber‘:pageNumber,‘pageSize‘:pageSize};//请求数据
             $(function () {
             	  $.ajax({
             	        type:"POST",
             	        url:url,
             	        data:reqParams,
             	        async:false,
             	        dataType:"json",
             	        success: function(data){
             	            if(data.isError == false) {
             	           // options.totalPages = data.pages;
             	        var newoptions = {
                        currentPage: 1,  //当前页数
                        totalPages: data.pages==0?1:data.pages,  //总页数
                        size:"normal",
                        alignment:"center",
                        itemTexts: function (type, page, current) {
                        switch (type) {
                            case "first":
                            return "第一页";
                            case "prev":
                            return "前一页";
                            case "next":
                            return "后一页";
                            case "last":
                            return "最后页";
                        case "page":
                        return  page;
                }
            },
            onPageClicked: function (e, originalEvent, type, page) {
            	var userName = $("#textInput").val(); //取内容
            	buildTable(userName,page,PAGESIZE);//默认每页最多10条
            }
         }
         $(‘#bottomTab‘).bootstrapPaginator("setOptions",newoptions); //重新设置总页面数目
         var dataList = data.dataList;
         $("#tableBody").empty();//清空表格内容
         if (dataList.length > 0 ) {
             $(dataList).each(function(){//重新生成
             	    $("#tableBody").append(‘<tr>‘);
                    $("#tableBody").append(‘<td>‘ + this.userId + ‘</td>‘);
                    $("#tableBody").append(‘<td>‘ + this.userName + ‘</td>‘);
                    $("#tableBody").append(‘<td>‘ + this.userPassword + ‘</td>‘);
                    $("#tableBody").append(‘<td>‘ + this.userEmail + ‘</td>‘);
                    $("#tableBody").append(‘</tr>‘);
             	    });
             	    } else {
             	          $("#tableBody").append(‘<tr><th colspan ="4"><center>查询无数据</center></th></tr>‘);
             	    }
             	    }else{
             	          alert(data.errorMsg);
             	            }
             	      },
             	        error: function(e){
             	           alert("查询失败:" + e);
             	        }
             	    });
               });
        }

        //渲染完就执行
        $(function() {

        	//生成底部分页栏
            $(‘#bottomTab‘).bootstrapPaginator(options);     

        	buildTable("",1,10);//默认空白查全部

            //创建结算规则
            $("#queryButton").bind("click",function(){
            	var userName = $("#textInput").val();
            	buildTable(userName,1,PAGESIZE);
            });
        });
    </script>
</body>
</html>

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

6、最终运行结果

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

结果如下:

打印出来的一些日志:

后台返回给前台的就是json

整个工程下载

版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka

时间: 2024-10-25 17:07:42

Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)的相关文章

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

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文实现了一个后台由Spring+Mybatis+SpringMVC组成,分页采用PageHelper,前台展示使用bootstrap-paginator来显示效果的分页实例.整个项目由maven构成.这里主要讲了分页的实例,框架怎么搭建就不再说明,主要是在这里的基础上来增加分页功能的.注意,此文是在这个基础 Spring+Mybatis+SpringMVC+Maven+MySql搭建

Spring+Mybatis+SpringMVC后台与前台分页展示实例

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

【转】Spring+Mybatis+SpringMVC+Maven+MySql搭建实例

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何使用Maven来搭建Spring+Mybatis+SpringMVC+MySql的搭建实例,文章写得很详细,有代码有图片,最后也带有运行的效果. 本文工程免费下载 一.准备工作 1. 首先创建一个表: CREATE TABLE `t_user` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_NAME` char(3

Spring+Mybatis+SpringMVC+Maven+MySql搭建实例

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何使用Maven来搭建Spring+Mybatis+SpringMVC+MySql的搭建实例,文章写得很详细,有代码有图片,最后也带有运行的效果. 一.准备工作 1. 首先创建一个表: CREATE TABLE `t_user` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_NAME` char(30) NOT NU

Spring+Mybatis+SpringMVC整合

这是来到博客园的第一篇文章,做java开发也好几年了,想从现在开始,在这里将自己会的.学到的做个系统的整理,便于自己掌握的更深.也便于以后复习.还便于给刚入门的攻城师们一点点参考(嘿嘿)--好了,废话不多说,第一篇文章就从最基本的javaWeb开发的三大框架整合开始. 至于为什么是从Spring+Mybatis+SpringMVC开始,而不是Spring+Struts+Hibernate,那是因为现在各个公司使用Spring+Mybatis+SpringMVC的越来越多,而Struts则是使用率

Spring+Mybatis+SpringMVC+Maven+MySql搭建实例(转)

文章转自http://www.cnblogs.com/cnndevelop/p/7029367.html 1. 首先创建一个表: CREATE TABLE `t_user` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_NAME` char(30) NOT NULL, `USER_PASSWORD` char(10) NOT NULL, `USER_EMAIL` char(30) NOT NULL, PRIMARY KEY (`USER_I

java高级软件架构师实战视频教程 Spring+Mybatis+SpringMVC+Ehcache+Memcached+Redis+Nginx+Varnish+ActiveMQ+Keepalived+MySQL+MongoDB

java高级软件架构师实战阶段1视频教程 迅雷下载  百度云 第001节:整体课程概览第002节:分模块.分工程管理第003节:多模块多Web应用合并War包第004节:Git基本原理和安装配置使用第005节:TortoiseGit的本地使用第006节:Egit的本地使用第007节:远程使用以及冲突解决第008节:基本业务功能和数据字典第009节:搭建基础的开发环境第010节:Spring+Mybatis实现DAO第011节:Mybatis的分页实现第012节:Service的实现以及模块化第0

集成代码生成器 单表 多表 树形表 一对多 springmvc spring mybatis SSM 后台框架

获取[下载地址]   QQ: 313596790   [免费支持更新] 三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; QQ:313596790 freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块 B 集成阿里巴巴数据库连

【集成代码生成器】 单表 多表 树形表 一对多 springmvc spring mybatis SSM 后台框架

获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Dr