Integration of SSM

The view layer Thymeleaf
Control layer Spring MVC
The business layer Spring business functions, transactions
Data access layer MyBatis

Spring integrates MyBatis with Spring MVC and provides business layer transaction management.

Spring MVC is part of Spring itself, so integration is relatively simple.

Integrating MyBatis requires the use of the integration plug-in provided by the MyBatis community, rather than the integration plug-in MyBatis -Spring provided by Spring.

The main reason is that MyBatis came later than Spring.

Integrated plugin official website: mybatis.org/spring/zh/i…

The results of SSM integration are:

  • MyBatis is easier to use
  • The beans in MyBatis, such as sqlSessionFactory and the dynamic proxy class of the Mpper interface, are managed by Spring’s IoC container.
  • Apply Spring’s declarative transaction capabilities to the business layer.
  • Integrate Spring MVC (mainly the use of Context Loader Listener, other no difference)

Spring integration with MyBatis

1. Create a project and create a package

  • The controller package
  • The entity package
  • Mapper package
  • Service package (IMPL package)
  • The test test package
  • pom.xml

2. Add dependencies

  • Mysql driver
  • Druid data source
  • Logback Log framework
  • lombok
  • Junit5 testing framework +spring 5 test dependency
  • MyBatis core dependencies
  • Spring-MyBatis
  • Spring ORM relies on object-relational mapping to write mapper
  • Servlet dependency [Implementation basis of master Controller]

Spring MVC related, view layer

  • SpringMVC relies on webMVC
  • Spring and Thymeleaf’s integration relies on the use of form echo and so on
  • MyBatis paging plugin if there is a paging requirement
<dependencies>
    <! - MySQL driver - >
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.3</version>
    </dependency>
    <! --Druid data source -->
    <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 testing framework
    <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 core dependencies -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <! --MyBatis and Spring integration dependencies -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.6</version>
    </dependency>
    <! --Spring ORM dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>5.3.1</version>
    </dependency>
    <! - the Servlet dependence - >
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <! -- SpringMVC dependencies, including Spring dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.1</version>
    </dependency>
    <! -- Spring and Thymeleaf integrate dependencies -->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
        <version>3.0.12. RELEASE</version>
    </dependency>
    <! MyBatis paging plugin -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

Copy the code

3. Add the log file logback.xml


      
<configuration debug="true">
    <! -- Specify log output location -->
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <! -- Log output format -->
            <! Time, log level, thread name, class to print logs, log body content, newline -->
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
        </encoder>
    </appender>
    <! -- Set the global log level. The log levels are DEBUG, INFO, WARN, and ERROR -->.
    <! -- Specifies that only logs at the current and later levels are printed at any log level. -->
    <root level="INFO">
        <! -- Specify the appender to print logs. Here we reference the previously configured appender with "STDOUT".
        <appender-ref ref="STDOUT" />
    </root>

    <! -- Specify the local log level according to special requirements -->
    <logger name="org.springframework.web.servlet.DispatcherServlet" level="DEBUG" />
    <! -- Package-level logging Settings -->
    <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>

Copy the code

4. Configure the data source

1 Properties file jdbc.properties

jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/mybatis-example
jdbc.driver=com.mysql.jdbc.Driver
Copy the code

Do not use username as the attribute name, it will be invalid

2 configuration Druid

Create a spring configuration file: spring-persist. XML

<! -- Import properties file -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

<! Druid - configuration - >
<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>

Copy the code

3 test Druid

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

5. Integrate MyBatis

1 MyBatis configuration file


      
<! DOCTYPEconfiguration
        PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <! -- Import external properties file -->
    <properties resource="jdbc.properties"></properties>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>
    <typeAliases>
        <! Alias all entity classes in this package. The alias is the first letter of the class name, but nothing else.
        <package name="com.dyy.entity"/>
    </typeAliases>
    <! Environments Many development environments and specify the default development environment -->
    <environments default="development">
        <! -- one of the development environments needs to have id-->
        <environment id="development">
            <! -- transaction manager type="JDBC", meaning transactions using 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>
    <! -- Specify location of mapping file -->
    <mappers>
        <mapper resource="mappers/EmployeeMapper.xml"></mapper>
    </mappers>
</configuration>

Copy the code

2 configuration sqlSessionFactoryBean

<! SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <! -- Data source -->
    <property name="dataSource" ref="dataSource"></property>
    <! If the mapping file is in the same package as the Mapper interface, you can omit this configuration.
    <property name="mapperLocations" value="classpath:com/dyy/mapper/*Mapper.xml"></property>
    <! -- Entity class type alias -->
    <property name="typeAliasesPackage" value="com.dyy.entity"></property>
    <! -- Configure global 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>

Copy the code

Configure SqlSessionFactory, which is a factory Bean that returns not the Bean of SqlSessionFactory, but the value returned by the getObject() method — SqlSessionFactory

3 Configure a Mapper interface scanner

<! -- Configure Mapper interface scanner -->
<! -- Mode 1 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.dyy.mapper"></property>
</bean>
<! Mybatis :scan base-package="com.dyy.mapper"></mybatis :scan> -->

Copy the code

Configuration MapperScannerConfigurer:

In fact, there are other ways to integrate MyBatis, this is the most powerful. This is a powerful feature that allows it to scan specific packages and automatically help us create the Mapper in batches, which greatly reduces the configuration effort.

Underneath, Spring’s default naming strategy for automatically detected components is adopted, which is to use the first letter of the class/interface name, otherwise unchanged, as the mapper name. For example, after the mapping interface UserMapper is scanned, the mapping bean created is named UserMapper.

4 develop MyBatis business

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

Copy the code
2 Mapper Indicates the EmployeeMapper interface
public interface EmployeeMapper {
    public List<Employee> findAll(a);
    public int saveEmp(Employee employee);
}
Copy the code
3 Mapping file employeemapper.xml

      
<! DOCTYPEmapper
        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>

Copy the code
4 test integration of MyBatis
@SpringJUnitConfig(locations = {"classpath:spring-persist.xml"})
public class TestSSM {
    @Autowired
    private EmployeeMapper employeeMapper;
    @Test
    public void testFindAll(a){
        List<Employee> employeeList = employeeMapper.findAll();
        employeeList.forEach((emp)-> System.out.println(emp));
    }
    @Test
    public void testSaveEmp(a){
        Employee emp = new Employee(null."zhangsan".678.0);
        employeeMapper.saveEmp(emp);
    }
@Test
public void testIoC(a){
    ApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:spring-persist.xml");
    String[] arr = context.getBeanDefinitionNames();
    for(String elem :arr){ System.out.println(elem); }}}Copy the code

Spring manages business layer transactions

1 Add a service layer

1 Add interfaces at the service layer

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

Copy the code

2 Add a service layer implementation class

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

    @Autowired
    private EmployeeMapper employeeMapper;
    @Override
    public List<Employee> findAll(a) {
        return this.employeeMapper.findAll();
    }
    @Override
    public int saveEmp(Employee employee) {
        return this.employeeMapper.saveEmp(employee);
    }
    // Simulate a transaction, expecting to be rolled back on a single failure
    @Override
    public int saveEmp2(Employee employee, Employee employee2) {
       int n1 =   this.employeeMapper.saveEmp(employee);
       int n2 =   this.employeeMapper.saveEmp(employee2);
       returnn1+n2; }}Copy the code

3 Scan for service layer annotations

<! -- Scan business layer annotations -->
<context:component-scan base-package="com.dyy.service"></context:component-scan>

Copy the code

4 Test: No transaction is found

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

2 Add a business layer transaction

Configure the transaction manager + start transaction annotations

<! -- Configure transaction manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<! -- Configure transaction annotation driver -->
<tx:annotation-driven></tx:annotation-driven>

Copy the code

Add transaction functionality to business layer methods

The @Transactional annotation needs to be added to the corresponding method.

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

Copy the code

3 Test transaction functionality

<logger name="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
level="DEBUG"></logger>
Copy the code

3. Spring integrate Spring MVC

1 Environment Preparation

1 Turn Java projects into Web projects

You can use the JBLJavaToWeb plug-in. After conversion, check whether WAR is in poM.

2web.xml

<! --ContextLoaderListener create IoC container -->
<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 Master Controller -->
<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>

<! --> < span style = "max-width: 100%; clear: both;
<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 request conversion
<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>

Copy the code

3Spring-mvc.xml

<! -- Scan controlle annotations -->
<context:component-scan base-package="com.dyy.controller"></context:component-scan>
<! -- Enable SpringMVC annotation driver -->
<mvc:annotation-driven></mvc:annotation-driven>
<! Static resource access problem -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<! Configure the view controller -->
<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>

Copy the code

4 Deploy the project and run it

You can use Idea bound Tomcat or tomcat7-maven-plugin.

If you use the Tomcat plug-in, do not use Tomcat8, there will be problems.

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <! -- Set port number for tomcat startup -->
        <port>8081</port>
        <! -- Configure the context path of the project -->
        <path>/mvnweb</path>
      </configuration>
    </plugin>
  </plugins>
</build>
Copy the code

2 Query all employees

@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"; }}Copy the code

1 Controller Development

@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"; }}Copy the code

2 Development Page

<tbody  th:if="${#lists.isEmpty(empList)}">
    <tr>
        <td colspan="5">No employee</td>
    </tr>
    <tr>
        <td colspan="5">
            <a th:href="@{/employee/page/add}">Add a page</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}">Modify the</a>
            <a th:hef="@{adf}">delete</a>
        </td>
    </tr>
        <td colspan="5">
            <a th:href="@{/employee/page/add}">Add a page</a>
        </td>
    </tr>
</tbody>

Copy the code

3 test

.

3 Adding employees

1 Configure a view controller

<mvc:view-controller path="/employee/page/add" view-name="empAdd.html"></mvc:view-controller>
Copy the code

2 Development Page

<h3>Add employees</h3>
<form th:action="@{/employee}" method="post">The name<input type="text" name="empName"><br>salary<input type="text" name="empSalary"><br>
    <input type="submit" value="Submit">
</form>

Copy the code

3 Controller Development

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

4. Paging function under SSM integration

1 Understanding paging

Benefits of paging

  • Good user experience
  • The server queries only a portion of data at a time, reducing the memory pressure.
  • The system performance is optimized by reducing the number of queries for cold data.

Paging SQL statements

It is actually executed with the following statement.

select emp_id,emp_name,emp_salary from t_emp limit 0.5; Query first page dataselect emp_id,emp_name,emp_salary from t_emp limit 5.5; Select * from page 2select emp_id,emp_name,emp_salary from t_emp limit 10.5; Select * from page 3Copy the code

The following formula can be summarized

limit(pageNum-1)*pageSize,pageSize;

The three basic elements of paging

  • Current page number: pageNum, pageIndex
  • Number of records per page: pageSize
  • Total number of records: totalCount

Other elements of paging: Calculated from the base elements

  • Total pages: Pages
  • Previous page: prePage
  • NextPage: nextPage
  • First page: isFirstPage
  • Last page: isLastPage
  • Whether there is previous page: hasPreviousPage
  • Is there a next page: hasNextPage
  • All navigation page numbers: navigatepageNums

2 Paging plug-in

To simplify code and speed up development, we can choose to use existing open source plug-ins.

PageHelper is a plugin for MyBatis framework to support pagination in MyBatis. It is very convenient to use.

GitHub

Github.com/pagehelper/…

Yards cloud

Gitee.com/free/Mybati…

use

1 Adding a Dependency
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

Copy the code
Inject the plugin properties into the sqlSessionFactoryBean
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageInterceptor">
                <property name="properties">
                    <props>
          <! -- Set a reasonable page number to true. Valid range of page number: 1~ total page number -->
                        <prop key="reasonable">true</prop>
                    <!-- 数据库方言:同样都是 SQL 语句,拿到不同数据库中,在语法上会有差异 -->
                        <! By default, MySQL is used as the database dialect.
                        <prop key="helperDialect">mysql</prop>
                    </props>
                </property>
            </bean>
        </array>
    </property>
</bean>

Copy the code
3 Paging operations
① Development of controller
@Override
public PageInfo findEmp(Integer pageNum, Integer pageSize) {
    // Enable paging. When enabled, subsequent SELECT statements are automatically appended with a LIMIT clause.
    // The total number of records is automatically queried
    PageHelper.startPage(pageNum,pageSize);
    // Query all data
    List<Employee> empList = this.employeeMapper.findAll();
    // Return data
    return new PageInfo(empList);
}

Copy the code
② Develop the business layer
<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="#">Modify the</a>
        <a href="#">delete</a>
    </td>
</tr>
<tr>
    <td colspan="10">
        <span th:if="${pageInfo.hasPreviousPage}">
             <a th:href="@{/employee/get/page/1}">Home page</a>
            <a th:href="@{|/employee/get/page/${pageInfo.prePage}|}">The previous page</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}|}">The next page</a>
            <a th:href="@{|/employee/get/page/${pageInfo.pages}|}">At the end of the page</a>
        </span>
        <span th:text="|${pageInfo.pageNum}/${pageInfo.pageSize}|"></span>
    </td>
</tr>

Copy the code
③ Develop the view layer
<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="#">Modify the</a>
        <a href="#">delete</a>
    </td>
</tr>
<tr>
    <td colspan="10">
        <span th:if="${pageInfo.hasPreviousPage}">
             <a th:href="@{/employee/get/page/1}">Home page</a>
            <a th:href="@{|/employee/get/page/${pageInfo.prePage}|}">The previous page</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}|}">The next page</a>
            <a th:href="@{|/employee/get/page/${pageInfo.pages}|}">At the end of the page</a>
        </span>
        <span th:text="|${pageInfo.pageNum}/${pageInfo.pageSize}|"></span>
    </td>
</tr>

Copy the code

The details of the PageHelper

Problem 1: Calling findAll() returns empList, passed as an argument to the PageInfo object. How are the other page attributes of the PageInfo class calculated?

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

Copy the code

Explanation:

The return value of this method is actually Page, a subclass of ArrayList that contains not only EMP data but also various paging properties. That is, the EMP data and various paging attributes are included in the return value of the findAll() method, and entering PageInfo is just a structural transformation.

Question 2: Since Pge already has paged employee data, as well as the various attributes of the Page, why does it need to be encapsulated in PageInfo, can not directly return Page?

Explanation:

Actually, yes. NavigatepageNums, Navigatepages, prePage, nextPage, startRow, and endRow are not available.