SSM的整合,分页插件的使用(五)

·  阅读 109

SSM整合

视图层Thymeleaf
控制层Spring MVC
业务层Spring 业务功能,事务
数据访问层MyBatis

​ 由Spring来整合MyBatis和Spring MVC,并提供业务层事务管理。

​ Spring MVC 本身就是Spring的一部分,所以整合相对简单。

​ 整合MyBatis需要使用MyBatis社区来提供的整合插件,而不是由Spring来提供的整合插件mybatis-spring。

​ 主要原因是因为MyBatis出现的比Spring晚。

整合插件官网:mybatis.org/spring/zh/i…

SSM整合的结果是:

  • MyBatis的使用更加简单
  • MyBatis中的Bean,比如sqlSessionFactory、Mpper接口的动态代理类都交给Spring的IoC容器管理。
  • 对业务层应用Spring的声明式事务功能。
  • 整合Spring MVC(主要是Context Loader Listener的使用,其他无差别)

一、Spring整合MyBatis

1.创建项目,创建包

  • controller包
  • entity包
  • mapper包
  • service包(impl包)
  • test测试包
  • pom.xml

2.添加依赖

  • mysql驱动
  • Druid数据源
  • logback日志框架
  • lombok
  • Junit5测试框架+spring 5 的test依赖
  • MyBatis核心依赖
  • Spring-MyBatis整合依赖【MyBatis提供】
  • Spring orm依赖 对象关系映射 写mapper用
  • Servlet 依赖【总控制器的实现基础】

Spring MVC相关,视图层

  • SpringMVC依赖【webmvc】
  • Spring和Thymeleaf的整合依赖 表单回显等使用
  • MyBatis分页插件 如果有分页需求
<dependencies>
    <!--MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.3</version>
    </dependency>
    <!--Druid数据源 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.31</version>
    </dependency>
    <!--logback日志框架 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
    <!--lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
    <!-- Junit5测试框架-->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>
    <!-- Spring5 test-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.3.1</version>
    </dependency>
    <!-- MyBatis核心依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!--MyBatis和Spring整合依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.6</version>
    </dependency>
    <!--Spring ORM依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>5.3.1</version>
    </dependency>
    <!--Servlet依赖 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- SpringMVC依赖,含Spring依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.1</version>
    </dependency>
    <!-- Spring和Thymeleaf整合依赖-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
        <version>3.0.12.RELEASE</version>
    </dependency>
    <!--MyBatis分页插件 -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

复制代码

3 .添加日志文件logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
    <!-- 指定日志输出的位置 -->
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日志输出的格式 -->
            <!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
        </encoder>
    </appender>
    <!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR -->
    <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
    <root level="INFO">
        <!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
        <appender-ref ref="STDOUT" />
    </root>

    <!-- 根据特殊需求指定局部日志级别 -->
    <logger name="org.springframework.web.servlet.DispatcherServlet" level="DEBUG" />
    <!--包级别的日志设置 -->
    <logger name="com.dyy.controller" level="DEBUG"></logger>
    <logger name="com.dyy.serivce" level="DEBUG"></logger>
<logger name="com.dyy.mapper" level="DEBUG"></logger>
</configuration>

复制代码

4.配置数据源

1 属性文件 jdbc.properties

jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/mybatis-example
jdbc.driver=com.mysql.jdbc.Driver
复制代码

不要使用username作为属性名,会莫名其妙失效

2 配置Druid

创建spring配置文件:spring-persist.xml【持久层】

<!--引入属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

<!-- 配置Druid-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

复制代码

3 测试Druid

@SpringJUnitConfig(locations = {"classpath:spring-persist.xml"})
public class TestSSM {
    @Autowired
    private DruidDataSource dataSource;
    @Test
    public void testDatasource() throws SQLException {
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

复制代码

5.整合MyBatis

1 MyBatis配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引入外部属性文件-->
    <properties resource="jdbc.properties"></properties>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>
    <typeAliases>
        <!-- 给该包下所有的实体类起别名,别名就是类名的首字母大写,其他不变-->
        <package name="com.dyy.entity"/>
    </typeAliases>
    <!--environments 很多开发环境,并指定默认的开发环境 -->
    <environments default="development">
        <!-- 其中的一个开发环境,需要有id-->
        <environment id="development">
            <!-- 事务管理器  type="JDBC",含义是使用JDBC的事务-->
            <transactionManager type="JDBC"/>
            <!--指定数据源,可能的取值  UNPOOLED  POOLED -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
           
            </dataSource>
        </environment>
    </environments>
    <!-- 指定映射文件的位置-->
    <mappers>
        <mapper resource="mappers/EmployeeMapper.xml"></mapper>
    </mappers>
</configuration>

复制代码

2 配置sqlSessionFactoryBean

<!--配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 数据源 -->
    <property name="dataSource" ref="dataSource"></property>
    <!-- 指定映射文件,如果映射文件和Mapper接口在同一个包下,可以省略该配置-->
    <property name="mapperLocations" value="classpath:com/dyy/mapper/*Mapper.xml"></property>
    <!--实体类类型别名 -->
    <property name="typeAliasesPackage" value="com.dyy.entity"></property>
    <!--配置全局Settings -->
    <property name="configuration">
        <bean class="org.apache.ibatis.session.Configuration">
            <property name="mapUnderscoreToCamelCase" value="true"></property>
            <property name="lazyLoadingEnabled" value="true"></property>
        </bean>
    </property>
</bean>

复制代码

配置SqlSessionFactory,这是一个工厂Bean,返回的不是SqlSessionFactory的Bean,而是getObject()方法的返回值——SqlSessionFactory

3 配置Mapper接口扫描器

<!--配置Mapper接口扫描器 -->
<!--方式1 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.dyy.mapper"></property>
</bean>
<!--方式2 
    <mybatis-spring:scan base-package="com.dyy.mapper"></mybatis-spring:scan>
 -->

复制代码

配置MapperScannerConfigurer:

​ 其实整合MyBatis还有其他方法,这个算是最给力的。这是一个强大的功能,让他扫描特定的包,自动帮我们成批的创建映射器Mapper,这样一来就能大大减少配置的工作量。

​ 底层采用了Spring针对自动侦测到的组件的默认命名策略亦即把类/接口名字的首字母小写,其他不变,作为映射器的名字。例如映射器接口UserMapper被扫描后创建的映射器bean名为userMapper。

4 开发MyBatis业务

1 实体类Employee
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    private Integer empId;
    private String empName;
    private Double empSalary;
}

复制代码
2 Mapper接口EmployeeMapper
public interface EmployeeMapper {
    public List<Employee> findAll();
    public int saveEmp(Employee employee);
}
复制代码
3 映射文件EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dyy.mapper.EmployeeMapper">
    <select id="findAll" resultType="employee">
        select * from t_emp
    </select>
    <insert id="saveEmp">
        insert into t_emp values (null,#{empName},#{empSalary})
    </insert>
</mapper>

复制代码
4 测试整合MyBatis
@SpringJUnitConfig(locations = {"classpath:spring-persist.xml"})
public class TestSSM {
    @Autowired
    private EmployeeMapper employeeMapper;
    @Test
    public void testFindAll(){
        List<Employee> employeeList = employeeMapper.findAll();
        employeeList.forEach((emp)-> System.out.println(emp));
    }
    @Test
    public void testSaveEmp(){
        Employee emp = new Employee(null,"zhangsan",678.0);
        employeeMapper.saveEmp(emp);
    }
@Test
public void testIoC(){
    ApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:spring-persist.xml");
    String[] arr = context.getBeanDefinitionNames();
    for(String elem :arr){
        System.out.println(elem);
    }
}
}

复制代码

二、Spring管理业务层事务

1 增加业务层

1增加业务层接口

public interface EmployeeService {
    public List<Employee> findAll();
    public int saveEmp(Employee employee);
    public int saveEmp2(Employee employee,Employee employee2);
}

复制代码

2增加业务层实现类

@Service(value = "employeeService")
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Override
    public List<Employee> findAll() {
        return this.employeeMapper.findAll();
    }
    @Override
    public int saveEmp(Employee employee) {
        return this.employeeMapper.saveEmp(employee);
    }
    //模拟事务,期望满足有一个失败就回滚
    @Override
    public int saveEmp2(Employee employee, Employee employee2) {
       int n1 =   this.employeeMapper.saveEmp(employee);
       int n2 =   this.employeeMapper.saveEmp(employee2);
       return n1+n2;
    }
}

复制代码

3扫描业务层注解

<!-- 扫描业务层注解-->
<context:component-scan base-package="com.dyy.service"></context:component-scan>

复制代码

4测试:发现没有事务

@SpringJUnitConfig(locations = {"classpath:spring-persist.xml"})
public class TestSSM {
    @Autowired
    private EmployeeService employeeService;
    @Test
    public void testSaveEmpServcie(){
        Employee emp = new Employee(null,"zhangsan",678.0);
        employeeService.saveEmp(emp);
    }
    @Test
    public void testSaveEmpServcie2(){
        Employee emp = new Employee(null,"lisi",678.0);
        Employee emp2 = 
new Employee(null,"wangwuwangwuwangwuwangwuwangwuwangwuwangwu",678.0);
        employeeService.saveEmp2(emp,emp2);
    }
}

复制代码

2添加业务层事务

1配置事务管理器+启动事务注解

<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务注解驱动-->
<tx:annotation-driven></tx:annotation-driven>

复制代码

2给业务层方法添加事务功能

需要在对应方法上添加@Transactional注解。

@Override
@Transactional
public int saveEmp2(Employee employee, Employee employee2) {
   int n1 =   this.employeeMapper.saveEmp(employee);
   int n2 =   this.employeeMapper.saveEmp(employee2);
   return n1+n2;
}

复制代码

3测试事务功能

<logger name="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
level="DEBUG"></logger>
复制代码

三、Spring整合Spring MVC

1 环境准备

1将Java项目变为Web项目

可以使用JBLJavaToWeb插件。转换完成后,核对pom中是否是<packaging>war</packaging>

2web.xml

<!--ContextLoaderListener 创建IoC容器 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-persist.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--SpringMVC总控制器 -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!--解决Post中文乱码问题 -->
<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>
<!--解决Restful下put、delete请求转换问题 -->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

复制代码

3Spring-mvc.xml

<!-- 扫描controlle注解-->
<context:component-scan base-package="com.dyy.controller"></context:component-scan>
<!--启用SpringMVC注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!--解决静态资源访问问题-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--配置视图控制器 -->
<mvc:view-controller path="/" view-name="portal.html"></mvc:view-controller>
<!--配置Thymeleaf视图解析器 -->
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="order" value="1"/>
    <property name="characterEncoding" value="UTF-8"/>
    <property name="templateEngine">
        <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
            <property name="templateResolver">
                <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                    <property name="prefix" value="/WEB-INF/templates/"/>
                    <property name="suffix" value=".html"/>
                    <property name="characterEncoding" value="UTF-8"/>
                    <property name="templateMode" value="HTML5"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

复制代码

4部署项目并运行

可以使用idea绑定的tomcat,也可以使用tomcat7-maven-plugin。

如果用tomcat插件,不要使用tomcat8,会出现问题。

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <!--配置tomcat启动的端口号-->
        <port>8081</port>
        <!--配置项目的上下文路径-->
        <path>/mvnweb</path>
      </configuration>
    </plugin>
  </plugins>
</build>
复制代码

2 查询所有员工

@Controller
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    @GetMapping
    public String findAll(Model model){
        List<Employee> employeeList = this.employeeService.findAll();
        model.addAttribute("empList",employeeList);
        return "empList";
    }
}

复制代码

1开发控制器

@Controller
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    @GetMapping
    public String findAll(Model model){
        List<Employee> employeeList = this.employeeService.findAll();
        model.addAttribute("empList",employeeList);
        return "empList";
    }
}

复制代码

2开发页面

<tbody  th:if="${#lists.isEmpty(empList)}">
    <tr>
        <td colspan="5">
            没有员工
        </td>
    </tr>
    <tr>
        <td colspan="5">
            <a th:href="@{/employee/page/add}">添加页面</a>
        </td>
    </tr>
</tbody>
<tbody  th:if="${!#lists.isEmpty(empList)}" >
    <tr th:each="emp,status:${empList}" th:class="${status.even ? 'white':'azure'}">
        <td th:text="${emp.empId}"></td>
        <td th:text="${emp.empName}"></td>
        <td th:text="${emp.empSalary}"></td>
        <td th:text="${status.even}"></td>
        <td>
            <a th:hef="@{ad}">修改</a>
            <a th:hef="@{adf}">删除</a>
        </td>
    </tr>
        <td colspan="5">
            <a th:href="@{/employee/page/add}">添加页面</a>
        </td>
    </tr>
</tbody>

复制代码

3测试

....

3 添加员工

1配置视图控制器

<mvc:view-controller path="/employee/page/add" view-name="empAdd.html"></mvc:view-controller>
复制代码

2开发页面

<h3>添加员工</h3>
<form th:action="@{/employee}" method="post">
    姓名 <input type="text" name="empName"><br>
    薪资 <input type="text" name="empSalary"><br>
    <input type="submit" value="提交">
</form>

复制代码

3开发控制器

@Controller
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;
    @PostMapping("")
    public String add(Employee emp){
        this.employeeService.saveEmp(emp);
        return "redirect:/employee";
    }
}

复制代码

四、SSM整合下的分页功能

1 理解分页

分页的好处

  • 用户体验较好
  • 服务器端每次只查询一部分数据,内存压力减小。
  • 对冷数据减少查询的次数,据此对系统性能进行优化。

分页的SQL语句

实际上是以下面这种语句执行的。

select emp_id,emp_name,emp_salary from t_emp limit 0,5; # 查询第一页数据
select emp_id,emp_name,emp_salary from t_emp limit 5,5; # 查询第二页数据
select emp_id,emp_name,emp_salary from t_emp limit 10,5;# 查询第三页数据
复制代码

可以总结出以下这个公式

limit(pageNum-1)*pageSize,pageSize;

分页的三个基本要素

  • 当前页号:pageNum,pageIndex
  • 每页的记录数:pageSize
  • 总的记录数:totalCount

分页的其他要素:根据基本要素计算而来

  • 总页数:pages
  • 前一页:prePage
  • 后一页:nextPage
  • 是否是第一页:isFirstPage
  • 是否是最后一页:isLastPage
  • 是否有前一页:hasPreviousPage
  • 是否有下一页:hasNextPage
  • 所有导航页号:navigatepageNums

2 分页插件

​ 为了简化代码,提高开发速度,我们可以选择使用已有的开源插件。

​ PageHelper是MyBatis框架的一个插件,用于支持在MyBatis执行分页操作,使用非常方便。

GitHub

github.com/pagehelper/…

码云

gitee.com/free/Mybati…

使用

1添加依赖
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

复制代码
2给sqlSessionFactoryBean注入插件属性
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageInterceptor">
                <property name="properties">
                    <props>
          <!-- 设置 reasonable 为 true 表示将页码进行合理化修正。页码的有效范围:1~总页数 -->
                        <prop key="reasonable">true</prop>
                    <!-- 数据库方言:同样都是 SQL 语句,拿到不同数据库中,在语法上会有差异 -->
                        <!-- 默认情况下,按照 MySQL 作为数据库方言来运行 -->
                        <prop key="helperDialect">mysql</prop>
                    </props>
                </property>
            </bean>
        </array>
    </property>
</bean>

复制代码
3分页操作
①开发控制器
@Override
public PageInfo findEmp(Integer pageNum, Integer pageSize) {
    //开启分页功能。开启后,后面执行的 SELECT 语句会自动被附加 LIMIT 子句,
    //而且会自动查询总记录数
    PageHelper.startPage(pageNum,pageSize);
    //查询数据:查询所有即可
    List<Employee> empList = this.employeeMapper.findAll();
    //返回数据
    return new PageInfo(empList);
}

复制代码
②开发业务层
<tr th:each="emp,status:${pageInfo.list}" th:class="${status.even?'white':'aliceblue'}">
    <td th:text="${emp.empId}"></td>
    <td th:text="${emp.empName}"></td>
    <td th:text="${emp.empSalary}"></td>
    <td th:text="${status.index}"></td>
    <td th:text="${status.even}"></td>
    <td>
        <a href="#">修改</a>
        <a href="#">删除</a>
    </td>
</tr>
<tr>
    <td colspan="10">
        <span th:if="${pageInfo.hasPreviousPage}">
             <a th:href="@{/employee/get/page/1}">首页</a>
            <a th:href="@{|/employee/get/page/${pageInfo.prePage}|}">上一页</a>
        </span>
        <span  th:each="num:${pageInfo.navigatepageNums}">
            <a th:if="${num != pageInfo.pageNum}" th:href=@{|/employee/get/page/${num}|} 
th:text="${num}"></a>
            <span th:if="${num == pageInfo.pageNum}"|} th:text="|[${num}]|"></span>
        </span>
        <span th:if="${pageInfo.hasNextPage}">
            <a th:href="@{|/employee/get/page/${pageInfo.nextPage}|}">下一页</a>
            <a th:href="@{|/employee/get/page/${pageInfo.pages}|}">末页</a>
        </span>
        <span th:text="|${pageInfo.pageNum}/${pageInfo.pageSize}|"></span>
    </td>
</tr>

复制代码
③开发视图层
<tr th:each="emp,status:${pageInfo.list}" th:class="${status.even?'white':'aliceblue'}">
    <td th:text="${emp.empId}"></td>
    <td th:text="${emp.empName}"></td>
    <td th:text="${emp.empSalary}"></td>
    <td th:text="${status.index}"></td>
    <td th:text="${status.even}"></td>
    <td>
        <a href="#">修改</a>
        <a href="#">删除</a>
    </td>
</tr>
<tr>
    <td colspan="10">
        <span th:if="${pageInfo.hasPreviousPage}">
             <a th:href="@{/employee/get/page/1}">首页</a>
            <a th:href="@{|/employee/get/page/${pageInfo.prePage}|}">上一页</a>
        </span>
        <span  th:each="num:${pageInfo.navigatepageNums}">
            <a th:if="${num != pageInfo.pageNum}" th:href=@{|/employee/get/page/${num}|} 
th:text="${num}"></a>
            <span th:if="${num == pageInfo.pageNum}"|} th:text="|[${num}]|"></span>
        </span>
        <span th:if="${pageInfo.hasNextPage}">
            <a th:href="@{|/employee/get/page/${pageInfo.nextPage}|}">下一页</a>
            <a th:href="@{|/employee/get/page/${pageInfo.pages}|}">末页</a>
        </span>
        <span th:text="|${pageInfo.pageNum}/${pageInfo.pageSize}|"></span>
    </td>
</tr>

复制代码

PageHelper的细节

问题1:调用findAll()方法返回是empList,并作为参数传给PageInfo对象。而PageInfo类的其他分页属性是如何计算出来的?

List<Employee> empList = this.employeeMapper.findAll();
PageInfo pageInfo = new PageInfo(empList);

复制代码

解释:

​ 这个方法的返回值其实是Page,是ArrayList的一个子类,不仅包含emp数据,也包括各种分页属性。也就是emp数据以及各种分页属性都是包含在findAll()方法的返回值中的,进入PageInfo只是进行了结构的转换。

问题2:既然Pge中已经有了分页的员工数据,以及分页的各个属性,为什么还要封装到PageInfo中,直接返回Page不可以吗?

解释:

其实可以。但是没有navigatepageNums、navigatepages、prePage、nextPage、startRow、endRow的相关信息,所以功能会少。

分类:
后端
标签:
分类:
后端
标签: