[TOC]

SpringMvc 响应流程image.png

项目结构

项目的构建

从原型创建
image.png
配置DarchetypeCatalog=internal
防止从网络获得项目配置
image.png
在Resource创建spring配置文件

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--  开启扫描  -->
    <context:component-scan base-package="cn.landsall"/>
    <!--  视图解析器对象  -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--  视图位置  -->
        <property name="prefix" value="/WEB-INF/pages/"/>
        <!--  视图后缀名  -->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--  开启SpringMvc框架注解的支持  -->
    <mvc:annotation-driven/>

</beans>

配置前端控制器

在web.xml中

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--  前端控制器加载spring配置文件  -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!--  servlet在启动项目时就加载,且顺序为1  -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

配置不截拦静态资源

spring.xml

<mvc:resources location="/static/" mapping="/static/**"/>

Controller

RequestMapping注解

  • 作用: 映射路径
  • 可以放在类(一级目录)或方法(二级目录)上
  • 注解属性
    • path,value
      • 指定映射路径
    • method
      • 指定方法的请求类型
      • image.png
    • params
      • 指定请求必须包含的参数(key和value)列表
      • image.png
    • headers
      • 指定必须包含的请求头
      • image.png

        请求参数的绑定

  • SpringMvc框架通过映射的方式将请求参数方法的参数绑定

    绑定普通数据

    请求参数必须和方法参数一一对应
    image.png

    绑定JavaBean

  • JavaBean中无引用对象

请求参数必须和JavaBean的属性对应
image.png

  • JavaBean中有引用对象

Account类中含有属性User user
image.png

绑定集合

Account中含有属性List list和Map map
image.png

绑定日期

image.png
image.png

自定义类型转换器

Spring对参数进行了自动的类型转换
如果要对日期等数据进行自定义转换
Convert接口
image.png
实现Convert接口
image.png
配置Spring.xml
image.png

返回值分类

返回视图

image.png

ModelAndView

image.png

响应ajax发送的值

发送零散的数据

  • JS

发送数据时使用$form.serialize()

//#submit提交按钮
$("#submit").on('click', function (event) {
    let $form = $("#login_form");

    $.ajax({
        url: "${pageContext.request.contextPath}/home/loginPost",
        type: 'post',
        data: $form.serialize(),  //Jquery方法序列化表单为查询字符串
        //contentType: "application/json;charset=UTF-8",
        dataType: 'text',
        success: function (data) {
            if (data === "succeed")
                location.href = "${pageContext.request.contextPath}/user/home"
            else if (data === "failed")
                alert("用户名或密码错误")
        },
        error: function () {
            alert("服务器错误")
        }
    });
    event.preventDefault();
});
  • 控制器

    @ResponseBody
    public String LoginPost(String username, String password, HttpSession httpSession) {
      User user = userService.userLogin(username, password);
    
      if (user != null) {
          httpSession.setAttribute("username", user.getUsername());
          return "succeed";
      } else {
          return "failed";
      }
    }
    

    发送JSON

    将请求体封装为Java对象和将返回值封装为JSON,需要引入jackson

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.11.0</version>
    </dependency>
    
  • js

    $("#submit").on('click', function (event) {
      let $form = $("#login_form");
      let obj = {}
    
      //jquery方法serializeArray()
      //将表单数据序列化为name=value的数组
      $.each($form.serializeArray(),function (index,data) {
          //将数据放入js对象
          obj[data.name] = data.value;
      })
    
      $.ajax({
          url: "${pageContext.request.contextPath}/home/loginPost",
          type: 'post',
          data: JSON.stringify(obj),  //Js原生方法 将JS对象序列化为JSON字符串
          contentType: "application/json;charset=UTF-8",
          dataType: 'text',
          success: function (data) {
              if (data === "succeed")
                  location.href = "${pageContext.request.contextPath}/user/home"
              else if (data === "failed")
                  alert("用户名或密码错误")
          },
          error: function () {
              alert("服务器错误")
          }
      });
      event.preventDefault();
    });
    
  • 控制器

    @ResponseBody
    public String LoginPost(@RequestBody User userPost, HttpSession httpSession) {
      User user = userService.userLogin(userPost.getUsername(), userPost.getPassword());
    
      if (user != null) {
          httpSession.setAttribute("username", user.getUsername());
          return "succeed";
      } else {
          return "failed";
      }
    }
    
  • serializeArray()序列化结果

image.png

上传文件

单服务器

  • 引入jar包 ```xml commons-io commons-io 2.8.0
commons-fileupload commons-fileupload 1.4 解析器->commons-fileupload->commons-io - **配置文件解析器**xml - **控制器** ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601780681927-5b48fc0e-b66a-43d0-b7b0-8fc8efdd2546.png#height=438&id=Z1Hws&margin=%5Bobject%20Object%5D&name=image.png&originHeight=875&originWidth=1454&originalType=binary&ratio=1&size=900686&status=done&style=none&width=727) <a name="s4Dbw"></a> ### 跨服务器 - **引入jar包**xml com.sun.jersey jersey-client 1.19.4 com.sun.jersey jersey-core 1.19.4 - **控制器** ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601783945086-37e86f80-3fd6-4da3-8275-c8147eb5e076.png#height=412&id=Tq4Ye&margin=%5Bobject%20Object%5D&name=image.png&originHeight=823&originWidth=1463&originalType=binary&ratio=1&size=821422&status=done&style=none&width=731.5) <a name="ueREw"></a> # 过滤器和拦截器 <a name="qGNYp"></a> ## 拦截器 拦截器执行流程<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601812409330-b06cb306-e831-49bb-af9b-239507c30e43.png#height=399&id=sjOLr&margin=%5Bobject%20Object%5D&name=image.png&originHeight=798&originWidth=1326&originalType=binary&ratio=1&size=94839&status=done&style=none&width=663)<br />PreHandle返回true时,无论之后的结果afterCompletion都会执行<br />PreHandle返回false时,后续的截拦器和控制器方法都不会执行,浏览器返回空视图(通常会设置页面跳转) - 创建类实现HandlerInterceptorjava public class MyInterceptor implements HandlerInterceptor { //控制器方法执行前(预处理) @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(“preHandle 1 执行”); return true; } //控制器方法执行后,视图解析前(后处理) @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(“postHandle 1 执行”); } //在DispatcherServlet完全处理完请求之后被调用,可用于清理资源,日志打印 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(“afterCompletion 1 执行”); } } - spring.xml配置拦截器xml 预处理和后处理方法都可以指定页面跳转<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601810943102-032e0b2c-6d8e-41c7-bc95-83eab5d1058c.png#height=264&id=CDD88&margin=%5Bobject%20Object%5D&name=image.png&originHeight=527&originWidth=484&originalType=binary&ratio=1&size=155996&status=done&style=none&width=242) <a name="OTlvz"></a> ## Spring中的过滤器 <a name="gfNH2"></a> ### CharacterEncodingFilterxml characterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 characterEncodingFilter / <a name="dd38c9c5"></a> # 异常处理 SpringMvc中的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。<br />![](https://cdn.nlark.com/yuque/0/2020/jpeg/1561124/1601801741003-29661068-18b7-42a3-b434-90d6b35f635d.jpeg#height=577&id=MdYZR&originHeight=577&originWidth=726&originalType=binary&ratio=1&size=0&status=done&style=none&width=726) <a name="3mJcA"></a> ## Spring自带异常解析器 <a name="8NMlK"></a> ### SimpleMappingExceptionResolverxml /WEB-INF/jsp/custom_error.jsp <a name="AG0P8"></a> ## 自定义异常解析器 - 创建自定义异常类 - 实现**HandlerExceptionResolver**接口java //自定义异常解析器 public class MyExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView modelAndView = new ModelAndView(); BaseException ex = null; if(e instanceof BaseException){ //如果是自定义异常则转换 ex = (BaseException)e; //分别处理不同的异常 if(ex instanceof SysException){ modelAndView.setViewName(“Exception/SysException”); }else if(ex instanceof UserException){ modelAndView.setViewName(“Exception/UserException”); } }else { //系统异常 ex = new BaseException(e.getMessage()); modelAndView.setViewName(“Exception/UnKnowException”); } //返回异常信息 modelAndView.addObject(“message”,ex.getMessage()); //返回视图 return modelAndView; } } `` - 配置自定义异常解析器 ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601803072677-f2b14c2f-ba23-4d91-829a-b87b20bcdfb8.png#height=100&id=HBxwR&margin=%5Bobject%20Object%5D&name=image.png&originHeight=199&originWidth=1243&originalType=binary&ratio=1&size=157232&status=done&style=none&width=621.5) <a name="nMDLS"></a> # 常用注解 <a name="DWtBy"></a> ### @RequestParam - 指定参数绑定的名称,默认为必须传值 ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601513532390-bf5c99f0-567d-4e66-b4ee-7343dc6b380b.png#height=102&id=qbEW9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=204&originWidth=930&originalType=binary&ratio=1&size=107762&status=done&style=none&width=465) <a name="rGkFc"></a> ### @RequestBody - 获得request请求体的值,对get请求不适用 - 常用在获取异步操作封装的值 ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601514004774-33aca6eb-bf55-4286-9eb1-6d654d97d434.png#height=125&id=ZQKhq&margin=%5Bobject%20Object%5D&name=image.png&originHeight=250&originWidth=765&originalType=binary&ratio=1&size=115595&status=done&style=none&width=382.5) <a name="r7UQp"></a> ### @ResponseBody - 表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,而不是解析为跳转路径,一般在异步获取数据时使用 - 相当于 resp.getWriter().write(); - 如果控制器返回String,则Ajax接收text - 如果控制器返回List,Map,单个对象等,则SpringMvc会自动封装为JSON(需要导入jackson) ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601714400071-a06b62f0-eacb-4c6e-ac16-0dfc54b5a4dd.png#height=255&id=KLhE7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=509&originWidth=1325&originalType=binary&ratio=1&size=465465&status=done&style=none&width=662.5) <a name="3aPbp"></a> ### @PathVariable - 将参数绑定到路径 - RESTful风格 - [http://www.ruanyifeng.com/blog/2014/05/restful_api.html](http://www.ruanyifeng.com/blog/2014/05/restful_api.html) ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601514543197-1fa44558-814d-4afa-b5f8-4f941f6ad844.png#height=106&id=OWmk1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=212&originWidth=846&originalType=binary&ratio=1&size=103910&status=done&style=none&width=423) <a name="EVddr"></a> ### @RequestHeader - 获取请求头的值(键值对) ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601515457614-082ef729-a2ee-420a-bd72-c05480e0757c.png#height=109&id=tjean&margin=%5Bobject%20Object%5D&name=image.png&originHeight=218&originWidth=1055&originalType=binary&ratio=1&size=134321&status=done&style=none&width=527.5) <a name="uN9XJ"></a> ### @CookieValue - 获取cookie中的值 ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601600388248-9b9a4747-f97c-462b-8762-0fe0b358c98c.png#height=135&id=g34B0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=269&originWidth=1076&originalType=binary&ratio=1&size=167693&status=done&style=none&width=538) <a name="yzCk2"></a> ### @ModelAttribute - 绑定Model中的值 **应用** 1. 当表单提交的不是完整实体类时,确保没有提交的字段使用原来数据库的数据 - 有返回值时 ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601601611550-e6a88b52-d399-4ffc-b21c-0e081cf9c8f7.png#height=359&id=KS7Ce&margin=%5Bobject%20Object%5D&name=image.png&originHeight=718&originWidth=642&originalType=binary&ratio=1&size=345287&status=done&style=none&width=321) - 无返回值时 ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1601601766653-a2ecbcdf-aa9f-4f9a-9498-2c9458c97662.png#height=340&id=B6JP9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=680&originWidth=931&originalType=binary&ratio=1&size=436461&status=done&style=none&width=465.5) <a name="Ve4A4"></a> ### @SessionAttributes - 将Model中的属性同步到session会话当中 -@SessionAttributes`设置的参数只用于*暂时的传递,而不是长期的保存,长期保存的数据还是要放到Session中 - 配置在类上 image.png
详解:
https://cloud.tencent.com/developer/article/1497784
https://stackoverflow.com/questions/18791645/how-to-use-session-attributes-in-spring-mvc
@SessionAttributes 除了可以通过属性名指定需要放到会 话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中 例如: 1. @SessionAttributes(types=User.class)会将model中所有类型为 User的属性添加到会话中。 1. @SessionAttributes(value={“user1”, “user2”}) 会将model中属性名为user1和user2的属性添加到会话中。 1. @SessionAttributes(types={User.class, Dept.class}) 会将model中所有类型为 User和Dept的属性添加到会话中。 1. @SessionAttributes(value={“user1”,“user2”},types={Dept.class})会将model中属性名为user1和user2以及类型为Dept的属性添加到会话中。 # SSM整合 xml <!--ssm--> <dependency> <groupId>org.singledog</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.3</version> </dependency> ## 项目构建 - maven ```xml org.apache.maven.plugins maven-compiler-plugin 8 8 war 5.2.7.RELEASE org.springframework spring-webmvc ${spring-version}
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring-version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring-version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring-version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring-version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${spring-version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring-version}</version>
</dependency>



<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring-version}</version>
</dependency>

<!--mybatis-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
</dependency>

<!--ssm-->
<dependency>
    <groupId>org.singledog</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.3</version>
</dependency>

<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.20</version>
</dependency>

<!--druid-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.22</version>
</dependency>


<!--servlet-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
</dependency>
<!--jstl-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<!--junit4-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>


- web.xml

加载Spring配置文件<br />加载Springmvc配置文件<br />配置前端控制器<br />中文乱码过滤器

```xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <listener>
        <!--  Spring监听器,默认加载WEB-INF目录下的applicationContext.xml配置文件  -->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--  设置配置文件路径  -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-config.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--  前端控制器加载spring配置文件  -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-config.xml</param-value>
        </init-param>
        <!--  servlet在启动项目时就加载,且顺序为1  -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--  解决中文乱码的过滤器  -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>
  • springmvc-config.xml

扫描控制器
配置视图解析器
静态资源

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--  扫描 Controller  -->
    <context:component-scan base-package="cn.landsall">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--  视图解析器对象  -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--  视图位置  -->
        <property name="prefix" value="/WEB-INF/pages/"/>
        <!--  视图后缀名  -->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--  不截拦静态资源  -->
    <mvc:resources location="/static/" mapping="/static/**"/>

    <!--  开启SpringMvc框架注解的支持  -->
    <mvc:annotation-driven/>

</beans>
  • spring-config.xml

扫描 Spring 和 Mybatis

<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!--  开启扫描,不处理 SpringMvc-->
    <context:component-scan base-package="cn.landsall">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--  配置连接池  -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://111.229.166.200:3306/ssm?serverTimezone=Asia/Shanghai" />
        <property name="username" value="admin" />
        <property name="password" value="cyl032512" />

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />
        <property name="maxActive" value="20" />
    </bean>

    <!--  配置 SqlSessionFactory  -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--  实体类别名 -->
        <property name="typeAliasesPackage" value="cn.landsall.entity"/>
         <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:/mapper/*.xml"/>
    </bean>

    <!--  配置 映射器 所在的包  -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.landsall.dao"/>
    </bean>


</beans>

pagehelper 分页

github: https://github.com/pagehelper/Mybatis-PageHelper
文档: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
API: https://apidoc.gitee.com/free/Mybatis_PageHelper/
实现原理: https://www.w3cschool.cn/mybatis/mybatis-ypsj3bpi.html
视频 : https://www.bilibili.com/video/BV1mE411X7yp?p=302

  • 5.X.X 版本

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

  • 集成SpringMvc

https://github.com/abel533/Mybatis-Spring

引入依赖jar包

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.X.X</version>
</dependency>

配置分页拦截器

参数

image.png
image.png

mybatis

  • 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="true"/>
        <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
        <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
        <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->
        <!-- 不理解该含义的前提下,不要随便复制该配置 
        <property name="params" value="pageNum=start;pageSize=limit;"/>    -->
    </plugin>
    </plugins>
    

    ssm

    <!--  配置 SqlSessionFactory  -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <!--  实体类别名 -->
      <property name="typeAliasesPackage" value="cn.landsall.entity"/>
      <!-- 分页插件 -->
      <property name="plugins">
          <array>
              <bean class="com.github.pagehelper.PageInterceptor">
                  <property name="properties">
                      <props>
                          <prop key="helperDialect">mysql</prop>
                          <prop key="reasonable">true</prop>
                      </props>
                  </property>
              </bean>
          </array>
      </property>
    </bean>
    

    使用

    在执行查询语句前调用静态方法

    PageHelper.startPage(currentPage,pageSize);
    List<Book> list = bookService.getAll();
    

    案例

  • BookList.jsp ```html

      <td><a href="${pageContext.request.contextPath}/book/detail/${book.id}">${book.bookName}</a></td>
      <td>${book.author}</td>
      <td>${book.publish}</td>
      <td><fmt:formatDate value="${book.publish_time}" pattern="yyyy-MM-dd"/></td>
      <td>${book.ISBN}</td>
      <td>${book.desc}</td>
      <td colspan="2">
          <a href="${pageContext.request.contextPath}/book/update/${book.id}">修改</a>
          <a href="${pageContext.request.contextPath}/book/del/${book.id}">删除</a>
      </td>
    

总条数 ${pageinfo.total} , 共 ${pageinfo.pages} 页 , 每页


- Controller.java
```java
@RequestMapping("/list/{currentPage}/{pageSize}")
public String List(ModelMap modelMap, @PathVariable int currentPage, @PathVariable int pageSize) {
    pageSize = pageSize > MinPageSize ? pageSize : MinPageSize;
    PageHelper.startPage(currentPage, pageSize);
    List<Book> list = bookService.getAll();

    PageInfo<Book> pageInfo = new PageInfo<>(list);
    //导航条逻辑
    int startPage = pageInfo.getPageNum();
    int subPage = (startPage % PageRange + PageRange - 1)%PageRange;
    startPage -= subPage;
    int endPage = startPage + PageRange - 1;
    endPage = Math.min(endPage, pageInfo.getPages());

    modelMap.addAttribute("startPage", startPage);
    modelMap.addAttribute("endPage", endPage);
    modelMap.addAttribute("pageinfo", pageInfo);

    return "BookList";
}

image.png