SSM整合
1、环境搭建
1.1、在project创建新module
1.2、选择maven
1.3、设置module名称和路径
1.4、module初始状态
1.5、配置打包方式和引入依赖
注意:默认的打包方式为 jar,为了能配置web资源,需要将打包方式设置为 war
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>online.liaojy</groupId>
<artifactId>spring_springmvc_mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--注意:properties标签只能有一个-->
<properties>
<spring.version>5.3.1</spring.version>
</properties>
<dependencies>
<!--spring的上下文依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring管理bean的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的依赖-->
<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-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring整合junit的依赖-->
<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.7</version>
</dependency>
<!--mybatis和spring的整合包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--分页插件的依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<!-- thymeleft日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI(前端控制器间接用到) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--springmvc处理json数据的依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<!--springmvc文件上传的依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
</project>
1.6、配置web资源目录
打开Project Structure,选择对应的module,并为该module创建一个web.xml文件
注意:web.xml文件需要放到web资源路径(工程路径\src\main\webapp)下
1.7、配置web.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、filter、servlet;
springmvc的ioc容器是在servlet初始化时创建;
springmvc的ioc管理的controller组件,依赖于spring的ioc管理的service组件;
因此,spring的ioc容器应该在filter或listener初始化时创建;
这样的话,springmvc的ioc创建controller组件时,便能从提前创建好的spring的ioc容器中找到service组件来完成自动装配;
Spring提供了一个监听器ContextLoaderListener,实现了ServletContextListener接口,
可监听ServletContext的状态,在web服务器启动时,读取Spring的配置文件
-->
<!--配置spring的监听器,在服务器启动时就加载spring配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--ContextLoaderListener监听器要求Spring配置文件的默认位置和名称为:/WEB-INF/applicationContext.xml-->
<!--通过上下文(即当前工程)初始化参数指定SpringMVC配置文件的位置和名称-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!--配置springMVC的编码过滤器(该过滤器须为第一个过滤器)-->
<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>
<init-param>
<!--该初始化参数用于设置响应参数也使用同样的编码方式-->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置处理请求方式的过滤器-->
<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>
<!--
前端控制器DispatcherServlet初始化时,会创建SpringMVC的ioc容器;
SpringMVC的ioc容器创建成功后,如果能找到已存在的Spring的ioc容器,则将Spring的ioc容器设置为其父容器;
子容器(SpringMVC的ioc容器)可以访问父容器(Spring的ioc容器)的bean组件,而父容器不能访问子容器的bean组件;
-->
<!--配置SpringMVC的前端控制器DispatcherServlet,对浏览器发送的请求统一进行处理-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通过初始化参数指定SpringMVC配置文件的位置和名称-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--将DispatcherServlet的初始化时间提前到服务器启动时-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.8、创建SpringMVC的配置文件
<?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--在指定的包中,扫描bean组件-->
<context:component-scan base-package="online.liaojy.ssm.controller"></context:component-scan>
<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" 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="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property>
</bean>
<!--开启默认servlet的处理器-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--开启mvc的注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--
视图控制器(mvc:view-controller):为指定的请求直接设置(逻辑)视图名称,从而实现页面的跳转
-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
</beans>
1.9、创建请求控制器
package online.liaojy.ssm.controller;
import org.springframework.stereotype.Controller;
/**
* @author liaojy
* @date 2023/12/3 - 18:32
*/
@Controller
public class EmployeeController {
}
1.10、创建模板目录及页面模板
注意:html要引入thymeleaf的约束:xmlns:th="http://www.thymeleaf.org"
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>index.html</h1>
</body>
</html>
1.11、创建jdbc.properties属性文件
注意:本例使用的数据库版本为 MySQL-5 ,因此驱动配置为 com.mysql.jdbc.Driver
如果使用的数据库版本为 MySQL-8 ,驱动配置应该为 com.mysql.cj.jdbc.Driver
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
1.12、创建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>
<!--引入jdbc.properties属性配置文件-->
<properties resource="jdbc.properties"/>
<!--全局配置-->
<settings>
<!--将下划线映射为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<!--<setting name="lazyLoadingEnabled" value="true"/>-->
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--配置类型别名-->
<typeAliases>
<package name="online.liaojy.ssm.pojo"/>
</typeAliases>
<plugins>
<!--设置分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<!--配置数据源-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--引入mapper映射文件-->
<mappers>
<package name="online.liaojy.ssm.mapper"/>
</mappers>
</configuration>
1.13、创建mapper接口
package online.liaojy.ssm.mapper;
/**
* @author liaojy
* @date 2023/12/4 - 7:00
*/
public interface EmployeeMapper {
}
1.14、创建mapper映射文件
注意:mapper映射文件的目录结构和名称要和mapper接口的一致
mapper映射文件的命名空间,也要和mapper接口的全类名一致
<?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="online.liaojy.ssm.mapper.EmployeeMapper">
</mapper>
1.15、创建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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--扫描组件(控制层除外)-->
<context:component-scan base-package="online.liaojy.ssm">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--引入jdbc.properties属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--配置数据源-->
<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.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--
事务管理都是基于connection对象来操作,而connection对象都是由数据源来管理;
因此,事务管理器需要配置数据源对象。
-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
开启事务的注解驱动(注意该标签有多个,要选命名空间为tx那个);
如果事务管理器的id为transactionManager,则transaction-manager属性不需要显示设置;
该标签的作用是:将使用@Transactional注解标识的方法(或标识的类的所有方法)进行事务管理
-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
<!--配置SqlSessionFactoryBean,用于为ioc容器提供SqlSessionFactory类型的bean组件-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--设置MyBatis核心配置文件的路径(如果MyBatis核心配置都是通过spring来指定,那可以不设置核心配置文件的路径)-->
<!--<property name="configLocation" value="classpath:mybatis-config.xml"></property>-->
<!--设置数据源-->
<property name="dataSource" ref="dataSource"></property>
<!--设置类型别名所对应的包-->
<property name="typeAliasesPackage" value="online.liaojy.ssm.pojo"></property>
<!--设置分页插件-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor"></bean>
</array>
</property>
<!--设置全局配置-->
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<!--将下划线映射为驼峰-->
<property name="mapUnderscoreToCamelCase" value="true"></property>
</bean>
</property>
<!--
设置映射文件的路径;
当配置了MapperScannerConfigurer的bean之后(见下文),如果mapper映射文件和mapper接口一致,则可以不需要设置;
当没配置MapperScannerConfigurer的bean,无论mapper映射文件和mapper接口是否一致,都必须设置映射文件的路径。
-->
<!--<property name="mapperLocations" value="classpath:mappers/*.xml"></property>-->
</bean>
<!--
配置mapper接口的扫描;
可以将指定包下所有的mapper接口,通过(当前SqlSessionFactory提供的)SqlSession来创建对应的代理实现类对象;
并将这些mapper接口的代理实现类对象交给ioc容器来管理。
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--
value属性既设置了mapper接口所在的包,也设置了mapper映射文件所在的包;
如果mapper映射文件和mapper接口所在的包不一致,
则需要在配置SqlSessionFactoryBean时(见上文),额外设置映射文件所在的包。
-->
<property name="basePackage" value="online.liaojy.ssm.mapper"></property>
</bean>
</beans>
1.16、创建业务层接口及实现类
package online.liaojy.ssm.service;
/**
* @author liaojy
* @date 2023/12/4 - 20:32
*/
public interface EmployeeService {
}
package online.liaojy.ssm.service.impl;
import online.liaojy.ssm.service.EmployeeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author liaojy
* @date 2023/12/4 - 20:34
*/
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
}
1.17、创建日志文件log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
1.18、配置tomcat
1.19、测试效果
2、实战案例
2.1、创建表
CREATE TABLE `t_emp` (
`emp_id` int(11) NOT NULL AUTO_INCREMENT,
`emp_name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2.2、插入数据
insert into t_emp (emp_name,age,sex,email) values ('a',18,'男','11@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('b',19,'男','22@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('c',20,'男','33@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('d',21,'男','44@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('e',22,'男','55@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('f',23,'男','66@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('g',24,'男','77@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('h',25,'男','88@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('i',26,'男','99@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('j',27,'男','00@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('k',28,'男','111@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('l',29,'男','222@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('m',30,'男','333@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('n',31,'男','444@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('o',32,'男','555@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('p',33,'男','666@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('q',34,'男','777@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('r',35,'男','888@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('s',36,'男','999@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('t',37,'男','000@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('u',38,'男','1111@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('v',39,'男','2222@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('w',40,'男','3333@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('x',41,'男','4444@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('y',42,'男','5555@qq.com');
insert into t_emp (emp_name,age,sex,email) values ('z',43,'男','6666@qq.com');
2.3、创建实体类
package online.liaojy.ssm.pojo;
import java.io.Serializable;
/**
* @author liaojy
* @date 2023/12/4 - 23:06
*/
public class Employee implements Serializable {
private Integer empId;
private String empName;
private Integer age;
private String sex;
private String email;
public Employee() {
}
public Employee(Integer empId, String empName, Integer age, String sex, String email) {
this.empId = empId;
this.empName = empName;
this.age = age;
this.sex = sex;
this.email = email;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Employee{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", email='" + email + '\'' +
'}';
}
}
2.4、持久层
/**
* 查询所有员工信息
* @return
*/
List<Employee> getAllEmployee();
<!--List<Employee> getAllEmployee();-->
<select id="getAllEmployee" resultType="Employee">
select * from t_emp
</select>
2.5、业务层
/**
* 查询所有员工信息
* @return
*/
List<Employee> getAllEmployee();
@Autowired
EmployeeMapper employeeMapper;
public List<Employee> getAllEmployee() {
return employeeMapper.getAllEmployee();
}
2.6、控制层
@Autowired
EmployeeService employeeService;
@GetMapping("/employee")
public String getAllEmployee(Model model){
// 查询所有员工信息
List<Employee> employees = employeeService.getAllEmployee();
//将员工信息共享到请求域
model.addAttribute("employees",employees);
//跳转到员工列表页面employee_list.html
return "employee_list";
}
2.7、页面视图
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>员工列表</title>
</head>
<body>
<table border="10">
<tr>
<!--表头合并七列-->
<th colspan="7">员工列表</th>
</tr>
<tr>
<th>序号</th>
<th>员工id</th>
<th>员工姓名</th>
<th>员工年龄</th>
<th>员工性别</th>
<th>员工邮箱</th>
<th>操作(<a href="">添加员工</a>)</th>
</tr>
<!--在thymeleaf语法中,要循环一个标签,只需要在该标签中添加循环属性即可-->
<!--循环元素变量(employee)后面那个(status)是thymeleaf提供的循环状态辅助变量-->
<tr th:each="employee,status : ${employees}">
<!--${status.count}表示循环次数,可以用来作为序号使用-->
<td th:text="${status.count}"></td>
<td th:text="${employee.empId}"></td>
<td th:text="${employee.empName}"></td>
<td th:text="${employee.age}"></td>
<td th:text="${employee.sex}"></td>
<td th:text="${employee.email}"></td>
<td>
<a href="">修改员工</a>
<a href="">删除员工</a>
</td>
</tr>
</table>
</body>
</html>
2.8、添加访问入口
<a th:href="@{/employee}">查询所有员工信息</a>
2.9、测试效果
3、分页优化
3.1、业务层
/**
* 分页查询所有员工信息
* @param pageNum
* @return
*/
PageInfo<Employee> getAllEmployeeWithPage(Integer pageNum,Integer pageSize);
public PageInfo<Employee> getAllEmployeeWithPage(Integer pageNum,Integer pageSize) {
// 在查询之前,开启分页功能,并设置当前页的页码和每页的数据条数
PageHelper.startPage(pageNum,pageSize);
// 查询所有的员工信息()
// 分页插件会在查询前先进行拦截,添加相关的sql分页代码后(因此在mapper映射文件编写的sql不能使用分号结束),再放行
List<Employee> employees = employeeMapper.getAllEmployee();
// 根据分页数据(employees)和分页导航的页码数(navigatePages),创建分页数据对象
PageInfo<Employee> employeePageInfo = new PageInfo<Employee>(employees, 5);
return employeePageInfo;
}
3.2、控制层
@GetMapping(value = {"/employee/page/{pageNum}","/employee/page/{pageNum}/{pageSize}"})
public String getAllEmployeeWithPage(Model model,
@PathVariable("pageNum") Integer pageNum,
@PathVariable(value = "pageSize",required = false) Integer pageSize){
// 判断请求中是否有设置每页的数据条数,没有的话就给一个默认值
if (pageSize == null){
pageSize = 4;
}
// 根据当前页的页码,分页查询所有员工信息
PageInfo<Employee> employeePageInfo = employeeService.getAllEmployeeWithPage(pageNum,pageSize);
//将分页数据共享到请求域
model.addAttribute("employeePageInfo",employeePageInfo);
//跳转到员工列表分页的页面employee_page.html
return "employee_page";
}
3.3、页面视图
关于分页数据对象的属性细节,请参考12.3.3.1节
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>员工列表</title>
</head>
<body>
<table border="10">
<tr>
<!--表头合并七列-->
<th colspan="7">员工列表</th>
</tr>
<tr>
<th>序号</th>
<th>员工id</th>
<th>员工姓名</th>
<th>员工年龄</th>
<th>员工性别</th>
<th>员工邮箱</th>
<th>操作(<a href="">添加员工</a>)</th>
</tr>
<!--在thymeleaf语法中,要循环一个标签,只需要在该标签中添加循环属性即可-->
<!--循环元素变量(employee)后面那个(status)是thymeleaf提供的循环状态辅助变量-->
<tr th:each="employee,status : ${employeePageInfo.list}">
<!--${status.count}表示循环次数,可以用来作为序号使用-->
<td th:text="${status.count}"></td>
<td th:text="${employee.empId}"></td>
<td th:text="${employee.empName}"></td>
<td th:text="${employee.age}"></td>
<td th:text="${employee.sex}"></td>
<td th:text="${employee.email}"></td>
<td>
<a href="">修改员工</a>
<a href="">删除员工</a>
</td>
</tr>
</table>
<!--分页导航-->
<div style="text-align: center;">
<!--如果存在上一页,则在分页导航中显示“首页”和“上一页”的导航超链接-->
<a th:if="${employeePageInfo.hasPreviousPage}" th:href="@{/employee/page/1}">首页</a>
<a th:if="${employeePageInfo.hasPreviousPage}" th:href="@{'/employee/page/'+${employeePageInfo.prePage}}">上一页</a>
<!--根据导航分页的页码数组,显示导航分页的页码-->
<span th:each="num : ${employeePageInfo.navigatepageNums}">
<!--如果循环的分页导航页码等于当前页码,则该分页导航页码加中括号突出显示,并标红-->
<a th:if="${employeePageInfo.pageNum == num}" th:href="@{'/employee/page/'+${num}}" th:text="'['+${num}+']'" style="color: red;"></a>
<!--如果循环的分页导航页码不等于当前页码,则该分页导航页码普通显示-->
<a th:if="${employeePageInfo.pageNum != num}" th:href="@{'/employee/page/'+${num}}" th:text="${num}"></a>
</span>
<!--如果存在下一页,则在分页导航中显示“下一页”和“末页”的导航超链接-->
<a th:if="${employeePageInfo.hasNextPage}" th:href="@{'/employee/page/'+${employeePageInfo.nextPage}}">下一页</a>
<a th:if="${employeePageInfo.hasNextPage}" th:href="@{'/employee/page/'+${employeePageInfo.pages}}">末页</a>
</div>
</body>
</html>
3.4、添加访问入口
<a th:href="@{/employee/page/1}">分页查询所有员工信息</a>
3.5、测试效果
如上图所示,当前页为第一页,所以在分页导航中没有“首页”和“上一页”,对应的页码带有中括号且标红
如上图所示,当前页为第二页,所以在分页导航中有“首页”和“上一页”,对应的页码带有中括号且标红
如上图所示,当前页为最后一页,所以在分页导航中没有“下一页”和“末页”,对应的页码带有中括号且标红
本文来自博客园,作者:Javaer1995,转载请注明原文链接:https://www.cnblogs.com/Javaer1995/p/17858710.html