首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

SSM 框架整合實現分頁功能完整教程:從 Maven 搭建到 PageHelper 最佳實踐

     編輯:Java 綜合教學

專案初始化(IDEA + Maven)

  1. Create New Project → Maven → 勾選 Create from archetype → webapp(或手動建目錄結構)
  2. GroupId:com.example,ArtifactId:ssm-page-demo
  3. 等待 IDEA 導入依賴,出現 BUILD SUCCESS

目錄結構標準化


ssm-page-demo
├─ src
│  ├─ main
│  │  ├─ java
│  │  │  └─ com.example.demo
│  │  │     ├─ controller
│  │  │     ├─ service
│  │  │     ├─ dao
│  │  │     ├─ entity
│  │  │     └─ util
│  │  ├─ resources
│  │  │  ├─ mapping          # MyBatis XML
│  │  │  ├─ spring-*.xml     # Spring 配置
│  │  │  ├─ db.properties
│  │  │  └─ log4j.properties
│  │  └─ webapp
│  │     ├─ WEB-INF
│  │     │  ├─ web.xml
│  │     │  └─ jsp
│  │     └─ static
│  └─ test
└─ pom.xml

核心依賴


<properties>
    <spring.version>5.3.25</spring.version>
    <mybatis.version>3.5.13</mybatis.version>
    <mysql.version>8.0.33</mysql.version>
    <druid.version>1.2.20</druid.version>
    <pagehelper.version>5.3.3</pagehelper.version>
</properties>

<dependencies>
    <!-- Spring 全家桶 -->
    <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</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-tx</artifactId><version>${spring.version}</version></dependency>
    <dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version><scope>test</scope></dependency>

    <!-- MyBatis + Spring 整合 -->
    <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency>
    <dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.7</version></dependency>

    <!-- PageHelper 分頁插件 -->
    <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pagehelper.version}</version></dependency>

    <!-- 連接池 Druid -->
    <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.20</version></dependency>

    <!-- MySQL 驅動 -->
    <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency>

    <!-- Web 基礎 -->
    <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency>
    <dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency>
    <dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency>

    <!-- JSON -->
    <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version></dependency>

    <!-- Lombok -->
    <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency>

    <!-- 日誌 -->
    <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.9</version></dependency>
    <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.20.0</version></dependency>
</dependencies>

關鍵配置文件

db.properties


jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/page_demo?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

spring-dao.xml(MyBatis 整合 + PageHelper 註冊)


<beans ...>
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- Druid 數據源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="initialSize" value="5"/>
        <property name="maxActive" value="20"/>
    </bean>

    <!-- SqlSessionFactory + PageHelper 插件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:mapping/*.xml"/>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <value>
                            helperDialect=mysql
                            reasonable=true
                            supportMethodsArguments=true
                            params=count=countSql
                        </value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

    <!-- 掃描 DAO 接口 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.demo.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
</beans>

spring-service.xml(事務管理)


<beans ...>
    <context:component-scan base-package="com.example.demo.service"/>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

spring-web.xml(MVC 配置)


<beans ...>
    <context:component-scan base-package="com.example.demo.controller"/>
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="prettyPrint" value="false"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    <mvc:default-servlet-handler/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

web.xml(Servlet 3.1、編碼過濾器、ContextLoader)


<web-app xmlns="https://xmlns.jcp.org/xml/ns/javaee"
         version="3.1">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-*.xml</param-value>
    </context-param>

    <filter>
        <filter-name>encodingFilter</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>
        <init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param>
    </filter>
    <filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

    <listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
    <listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-web.xml</param-value></init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

分頁實戰代碼

實體類


@Data @TableName("sys_record")
public class Record {
    private Long id;
    private String username;
    private String loginName;
    private String operateDate;
    private String business;
    private String note;
}

Mapper 接口 + XML


// RecordMapper.java
@Mapper
public interface RecordMapper {
    List<Record> selectByLoginName(@Param("loginName") String loginName);
    int countByLoginName(@Param("loginName") String loginName);
}

<mapper namespace="com.example.demo.dao.RecordMapper">
    <select id="selectByLoginName" resultType="Record">
        SELECT * FROM sys_record
        WHERE login_name = #{loginName}
        ORDER BY operate_date DESC
    </select>
    <select id="countByLoginName" resultType="int">
        SELECT COUNT(1) FROM sys_record WHERE login_name = #{loginName}
    </select>
</mapper>

註:無需手寫 LIMIT,PageHelper 會自動攔截並注入分頁 SQL。

Service 層


@Service
public class RecordService {
    @Autowired RecordMapper recordMapper;

    public PageInfo<Record> queryPage(String loginName, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);  // 核心:開啟分頁
        List<Record> list = recordMapper.selectByLoginName(loginName);
        return new PageInfo<>(list);             // 封裝總頁數、總條數、導航頁碼等
    }
}

Controller


@Controller
@RequestMapping("/record")
public class RecordController {
    @Autowired RecordService recordService;

    @GetMapping("/list")
    public String list(@RequestParam String loginName,
                       @RequestParam(defaultValue = "1") int pageNum,
                       @RequestParam(defaultValue = "10") int pageSize,
                       Model model) {
        PageInfo<Record> page = recordService.queryPage(loginName, pageNum, pageSize);
        model.addAttribute("page", page);
        return "record/list";
    }
}

JSP 分頁導航


<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<table>
    <c:forEach items="${page.list}" var="r">
        <tr>
            <td>${r.id}</td><td>${r.username}</td><td>${r.loginName}</td>
            <td>${r.operateDate}</td><td>${r.business}</td><td>${r.note}</td>
        </tr>
    </c:forEach>
</table>

<div class="pagination">
    <c:if test="${page.hasPreviousPage}">
        <a href="${pageContext.request.contextPath}/record/list?loginName=${param.loginName}&pageNum=1">首頁</a>
        <a href="${pageContext.request.contextPath}/record/list?loginName=${param.loginName}&pageNum=${page.prePage}">上一頁</a>
    </c:if>
    <span>第 ${page.pageNum} 頁 / 共 ${page.pages} 頁</span>
    <c:if test="${page.hasNextPage}">
        <a href="${pageContext.request.contextPath}/record/list?loginName=${param.loginName}&pageNum=${page.nextPage}">下一頁</a>
        <a href="${pageContext.request.contextPath}/record/list?loginName=${param.loginName}&pageNum=${page.pages}">尾頁</a>
    </c:if>
</div>

PageHelper 核心配置解析

參數推薦值說明
helperDialectmysql明確指定方言,避免自動識別失敗
reasonabletruepageNum<1 時查第一頁,>總頁數時查最後一頁
supportMethodsArgumentstrue支援 Mapper 方法參數傳遞 pageNum/pageSize
paramscount=countSql優化 Count 查詢(需 XML 定義 countSql)

Tomcat 部署與驗證

  1. IDEA → Add Configuration → Tomcat Server → Local
  2. Deployment 標籤 → + → Artifact → 選擇 ssm-page-demo:war exploded
  3. 啟動,訪問 https://localhost:8080/record/list?loginName=test

總結與避坑指南

坑點解決
PageHelper 不生效檢查 sqlSessionFactory.plugins 是否註冊 PageInterceptor,Mapper 方法是否在 PageHelper.startPage() 之後調用
Count 查詢慢配置 params=count=countSql,在 XML 寫專用 <select id="countSql">SELECT COUNT(1)...
JSP EL 表達式不生效web.xml version 必須 ≥ 2.4(建議 3.1),JSP 頁面 isELIgnored="false"
中文亂碼全鏈路 UTF-8:DB、連接池、Filter、JSP pageEncoding、Tomcat URIEncoding

現代化升級建議

  • 新專案優先 Spring Boot 3.x + MyBatis-Plus,@EnablePagination 一行啟用分頁,零 XML。
  • 前後端分離架構:Controller 返回 PageResult<T> JSON,前端 Vue/React + Ant Design Table 直接渲染。
  • 大數據量深分頁:改用 WHERE id > lastId LIMIT n 游標分頁,避免 OFFSET 掃描大量無用行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved