SpringMVC(9)——SSM整合

1 篇文章 0 订阅
1 篇文章 0 订阅

目录

前言

ContextLoaderListener监听器

前置工作(创建SSM项目并创建spring_listenner模块)

SSM入门

SSM正式整合

(前置工作)创建新的模块ssm

SSM整合Spring、SpringMVC

SSM整合Mybatis框架

SSM整合事务

(实践)SSM整合实现页面展示所有员工信息

(实践)SSM整合实现页面通过分页方式展示所有员工信息,并设置分页跳转的超链接


前言

  • 已经学习了Mybatis、spring、springMVC框架,现在需要把他整合
  • SpringMVC是一个表述层框架,用于接收浏览器的请求、参数、资源,然后将服务器的数据响应给浏览器
  • Mybatis帮我们连接数据库进行增删改查
  • spring是一个整合型框架,通过IOC容器管理对象(Mybatis的SqlSesion对象)和AOP(实现Mybatis的声明式事务)
  • Mybatis组件可以通过spring进行管理、springMVC与spring是同源的,他们可以用同一个配置文件(使用同一个IOC容器)也就是不整合;反而言之也可以不用同一个配置文件,也就是各自用各自的配置文件(spring一个IOC容器ApplicationContext,springMVC一个IOC容器WebApplicationContext),通过各自配置文件来自行管理自己的组件。推荐使用整合方式
  • 回顾之前我们在使用Spring的时候,都是通过手动代码获取IOC容器,然后再获取一个Bean进行操作,因为当时是在java代码,因此我们可以通过测试类手动创建spring的IOC容器。
    public class TestSpring5 {
        @Test
        public void testAdd() {
            //1 加载 spring 配置文件,ClassPathXmlApplicationContext()的configLocation参数是以src目录基础的
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("bean1.xml");
            //2 获取配置后创建的对象,参数分别为配置文件的<bean>标签的id属性值,还有要创建的类Class实例.用于创建运行时类
            User user = context.getBean("user", User.class);
            System.out.println(user);//com.atguigu.spring5.User@436e852b
            user.add();//add......
        }
    }
    但是后面变成了Web模块,也就是SpringMVC的IOC容器是在web.xml中配置DispathcerServlet前端控制器的时候初始化创建的,他是专门用来管理控制层Controller的组件(常用SpringMVC控制层组件:HandlerMapping、Handler、HandlerAdapter、ViewResolver、View)
  • 那么剩下的业务层、持久层的组件就要交给Spring的IOC容器管理。但是我们发现我们控制层在调用业务层进行代码操作时,是需要依赖业务层的组件的(例如:@Autowired注入一个Service层的Bean作为成员变量进行操作,这种叫自动装配,是在获取Spring的IOC容器的Bean才能完成的)
  • 至此我们发现springMVC的IOC有Controller有关的组件、Spring的IOC有Service和Dao有关的组件,我们SpringMVC的Controller层需要调用Spring的Service层,也就是Controller需要完成Service自动装配,那就是说SpringMVC依赖于Spring,Spring要比SpringMVC的IOC容器先要创建,也就是在DispathcerServlet初始化前先创建,这时候就会延伸到Web三大组件和执行顺序(监听器Listener-->过滤器Filter-->Servlet),需要通过Listener来实现Spring的IOC容器在DispathcerServlet之前创建(不使用过滤器因为Spring的IOC容器创建代码只需要执行一次,不需要每个请求进来都执行拦截和放行)

ContextLoaderListener监听器

  • 监听器常见有三种:ServletContextListener(第一个是监听ServletContext状态,里面有ServletContext初始化和销毁两个抽象方法,实际上就是用来监听服务器的启动和关闭执行的最早一个方法)、HttpSessionListener、ServletContextAttributeListener(后两个都是监听HttpSession状态),分析源码
    public class ContextLoaderListener extends ContextLoader implements ServletContextListener{
    
    ...
    
    	@Override
    	public void contextInitialized(ServletContextEvent event) {
    		initWebApplicationContext(event.getServletContext());//创建一个Web应用的IOC容器,进入该方法
    	}
    
    
    ...
    
    -->
    
    public class ContextLoader {
    
    ...
    
    	public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    		if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
    			throw new IllegalStateException(
    					"Cannot initialize context because there is already a root application context present - " +
    					"check whether you have multiple ContextLoader* definitions in your web.xml!");
    		}
    
    		servletContext.log("Initializing Spring root WebApplicationContext");
    		Log logger = LogFactory.getLog(ContextLoader.class);
    		if (logger.isInfoEnabled()) {
    			logger.info("Root WebApplicationContext: initialization started");
    		}
    		long startTime = System.currentTimeMillis();
    
    		try {
    			// Store context in local instance variable, to guarantee that
    			// it is available on ServletContext shutdown.
    			if (this.context == null) {
    				this.context = createWebApplicationContext(servletContext);//真正执行创建IOC容器的方法
    			}
    			if (this.context instanceof ConfigurableWebApplicationContext) {
    				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
    				if (!cwac.isActive()) {
    					// The context has not yet been refreshed -> provide services such as
    					// setting the parent context, setting the application context id, etc
    					if (cwac.getParent() == null) {
    						// The context instance was injected without an explicit parent ->
    						// determine parent for root web application context, if any.
    						ApplicationContext parent = loadParentContext(servletContext);
    						cwac.setParent(parent);
    					}
    					configureAndRefreshWebApplicationContext(cwac, servletContext);
    				}
    			}
    			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    
    			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
    			if (ccl == ContextLoader.class.getClassLoader()) {
    				currentContext = this.context;
    			}
    			else if (ccl != null) {
    				currentContextPerThread.put(ccl, this.context);
    			}
    
    			if (logger.isInfoEnabled()) {
    				long elapsedTime = System.currentTimeMillis() - startTime;
    				logger.info("Root WebApplicationContext initialized in " + elapsedTime + " ms");
    			}
    
    			return this.context;
    		}
    		catch (RuntimeException | Error ex) {
    			logger.error("Context initialization failed", ex);
    			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);//将IOC容器放到最大的应用域servletContext中
    			throw ex;
    		}
    	}
    
    ...
    
    }
  • 现在我们就是通过监听器监听ServletContext状态,判断服务器初始化启动,先加载Spring的配置文件、来创建Spring的IOC容器,然后在DispathcerServlet在初始化时完成Service层在Controller层的自动装配,也完成了SpringMVC的IOC容器创建,并且会设置SpringMVC的容器是Spring容器的子类,也就是完成SSM的SS整合,Spring和SpringMVC各自各自的配置文件及IOC容器。如果只是单纯SpringMVC,那么springMVC容器就是最高级的容器。子容器是可以访问父容器的,也就是springMVC组件(Bean)可以访问spring的组件(Bean),但是父容器不能访问子容器的(Bean),这里之前的文章DispathcerServlet初始化的时候提及过
  • Spring提供了监听器ContextLoaderListener实现类,他实现ServletContextListener接口,可监听ServletContext的状态,在web服务器的启动后第一个启动的方法(Serlvet初始化的方法中,比DispathcerServlet要早),读取Spring的配置文件,创建Spring的IOC容器,web应用中必须在web.xml中配置。监听器配置参考如下代码写在web.xml的<beans>根元素里面的内容
        <listener>
            <!--配置spring监听器,在服务器启动时第一个执行加载Spring的配置文件,
            因为这个类是写好的,因此Spring配置文件默认位置和名称为:/WEB-INF/applicationContext.xml,
            但并非绝对,可以通过编辑上下文参数自定义spring配置文件的位置和名称-->
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!--通过该模块上下文初始化参数设置spring配置文件的位置和名称-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.xml</param-value>
        </context-param>
    

前置工作(创建SSM项目并创建spring_listenner模块)

  1. 创建项目
  2. pom.xml
    <?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>com.atguigu</groupId>
        <artifactId>spring_listener</artifactId>
        <version>1.0-SNAPSHOT</version>
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <packaging>war</packaging>
    
        <dependencies>
            <!-- SpringMVC -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.3.1</version>
            </dependency>
            <!-- 日志 -->
            <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>
            <!-- Spring5和Thymeleaf整合包 -->
            <dependency>
                <groupId>org.thymeleaf</groupId>
                <artifactId>thymeleaf-spring5</artifactId>
                <version>3.0.12.RELEASE</version>
            </dependency>
        </dependencies>
    
    
    </project>
  3. 添加web模块的

SSM入门

  • 目的:创建springMVC和Spring的配置文件,然后把控制层交给SpringMVC进行管理,将业务层交给Spring管理,当Controller可以正常访问Service层时,说明Spring在Listener创建容器是没有问题的
  1. web.xml,配置springMVC的DispathcerServlet和Listener初始化Spring

    <?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">
        <!-- 配置SpringMVC的前端控制器,对浏览器发送的请求统一进行处理 -->
        <servlet>
            <servlet-name>springMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 通过初始化参数指定SpringMVC配置文件的位置和名称 -->
            <init-param>
                <!-- contextConfigLocation为固定值 -->
                <param-name>contextConfigLocation</param-name>
                <!-- 使用classpath:表示从类路径查找配置文件,例如maven工程中的
                src/main/resources -->
                <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>
            <!--
            设置springMVC的核心控制器所能处理的请求的请求路径
            除了.jsp以外的请求路径的请求
            -->
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
        <listener>
            <!--
            配置创建Spring的监听器,在服务器启动时加载Spring的配置文件
            Spring配置文件默认位置和名称:/WEB-INF/applicationContext.xml
            可通过上下文参数自定义Spring配置文件的位置和名称
            -->
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!--通过设置上下文自定义Spring配置文件的位置和名称-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.xml</param-value>
        </context-param>
    </web-app>
  2. springMVC核心配置文件只配置视图解析器和注解扫描,还有开启mvc注解驱动,还有开启首页视图接控制器

    <?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">
    
        <!-- 自动扫描包 -->
        <context:component-scan base-package="com.atguigu.controller"/>
        <!-- 配置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>
    
        <mvc:annotation-driven />
        <!--
            path:设置处理的请求地址
            view-name:设置请求地址所对应的视图名称
        -->
        <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
    
    </beans>
  3. 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"
           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">
    
        <!-- 自动扫描包 -->
        <context:component-scan base-package="com.atguigu.service.impl"/>
    
    </beans>
  4. 创建首页页面src\main\webapp\WEB-INF\templates\index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <h1>首页</h1>
    </body>
    </html>
  5. 创建SpringMVC组件请求控制器,还有通过自动装配Service层的Bean

    package com.atguigu.controller;
    
    import com.atguigu.service.HelloService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    @Controller
    public class HelloController {
        @Autowired
        private HelloService helloService;
    }
    
  6. 创建业务层的接口

    package com.atguigu.service;
    
    public interface HelloService {
    }
    
  7. 创建业务层接口的实现类,作为spring的组件

    package com.atguigu.service.impl;
    
    import com.atguigu.service.HelloService;
    import org.springframework.stereotype.Service;
    
    @Service
    public class HelloServiceImpl implements HelloService {
    }
    
  8. 配置tomcat服务器

  9. 重启服务器,测试效果,运行正常,Controller层也没有报错,证明Spring先创建,然后SpringMVC才能够自动装配Service层的组件

SSM正式整合

(前置工作)创建新的模块ssm

  1. 创建模块
  2. pom.xml
    <?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>com.atguigu.ssm</groupId>
        <artifactId>ssm</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <packaging>war</packaging>
    
        <!--自定义属性,用来统一管理各个依赖的版本-->
        <properties>
            <!--来统一管理spring依赖的版本-->
            <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>
            <!--spring声明事务用到这个jar包-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!--spring管理切面的-->
            <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.13.2</version>
                <scope>test</scope>
            </dependency>
            <!-- MySQL驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.16</version>
            </dependency>
            <!-- log4j日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper
             分页插件-->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>5.2.0</version>
            </dependency>
            <!-- 日志,是slf4j日志门面的实现 -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
            <!-- ServletAPI 作为Dispatcher的父类 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!--处理Json数据的-->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.12.1</version>
            </dependency>
            <!--文件上传依赖-->
            <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>
  3. 添加web模块
  4. 在sql数据中创建数据表里面存有员工信息
    -- --------------------------------------------------------
    -- 主机:                           127.0.0.1
    -- 服务器版本:                        10.5.12-MariaDB - mariadb.org binary distribution
    -- 服务器操作系统:                      Win64
    -- HeidiSQL 版本:                  11.3.0.6295
    -- --------------------------------------------------------
    
    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET NAMES utf8 */;
    /*!50503 SET NAMES utf8mb4 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
    
    
    -- 导出 ssm 的数据库结构
    CREATE DATABASE IF NOT EXISTS `ssm` /*!40100 DEFAULT CHARACTER SET utf8 */;
    USE `ssm`;
    
    -- 导出  表 ssm.t_emp 结构
    CREATE TABLE IF NOT EXISTS `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 AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;
    
    -- 正在导出表  ssm.t_emp 的数据:~30 rows (大约)
    /*!40000 ALTER TABLE `t_emp` DISABLE KEYS */;
    INSERT INTO `t_emp` (`emp_id`, `emp_name`, `age`, `sex`, `email`) VALUES
    	(1, 'a', NULL, NULL, NULL),
    	(2, 'a', NULL, NULL, NULL),
    	(3, 'a', NULL, NULL, NULL),
    	(4, 'a', NULL, NULL, NULL),
    	(5, 'a', NULL, NULL, NULL),
    	(6, 'a', NULL, NULL, NULL),
    	(7, 'a', NULL, NULL, NULL),
    	(8, 'a', NULL, NULL, NULL),
    	(9, 'a', NULL, NULL, NULL),
    	(10, 'a', NULL, NULL, NULL),
    	(11, 'a', NULL, NULL, NULL),
    	(12, 'a', NULL, NULL, NULL),
    	(13, 'a', NULL, NULL, NULL),
    	(14, 'a', NULL, NULL, NULL),
    	(15, 'a', NULL, NULL, NULL),
    	(16, 'a', NULL, NULL, NULL),
    	(17, 'a', NULL, NULL, NULL),
    	(18, 'a', NULL, NULL, NULL),
    	(19, 'a', NULL, NULL, NULL),
    	(20, 'a', NULL, NULL, NULL),
    	(21, 'a', NULL, NULL, NULL),
    	(22, 'a', NULL, NULL, NULL),
    	(23, 'a', NULL, NULL, NULL),
    	(24, 'a', NULL, NULL, NULL),
    	(25, 'a', NULL, NULL, NULL),
    	(26, 'a', NULL, NULL, NULL),
    	(27, 'a', NULL, NULL, NULL),
    	(28, 'a', NULL, NULL, NULL),
    	(29, 'a', NULL, NULL, NULL),
    	(30, 'a', NULL, NULL, NULL);
    /*!40000 ALTER TABLE `t_emp` ENABLE KEYS */;
    
    /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
    /*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;
    
  5. 配置web.xml,spring创建监听器、设置spring配置文件存放位置的上下文参数、参数解析过滤器、拓展请求方式过滤器、前端控制器
    <?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">
    
        <!-- 配置Spring的编码过滤器 -->
        <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>
    
        <!-- 配置SpringMVC的前端控制器 -->
        <servlet>
            <servlet-name>DispatcherServlet</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>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
        <!-- 配置Spring的监听器,在服务器启动时先加载spring的配置文件创建容器在考虑springMVC的 -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!-- 设置Spring的配置文件的位置和名称 -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.xml</param-value>
        </context-param>
    
    
    </web-app>

SSM整合Spring、SpringMVC

  1. 通过SpringMVC的核心配置文件搭建springMVC的框架,里面有他容器管理的组件,有扫描组件、Thymeleaf视图解析器、开启MVC注解驱动(否则所有请求只能被defalutServlet处理、否则只有设置了视图控制器的请求才会映射)、默认Servlet处理静态资源、配置访问首页视图控制器、文件解析器将二进制文件转换成MultipartFile对象、拦截器、异常控制器
    <?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:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--扫描组件,只扫描控制层-->
        <context:component-scan base-package="com.atguigu.ssm.controller">
        </context:component-scan>
        <!--配置视图解析器-->
        <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的注解驱动 -->
        <mvc:annotation-driven/>
    
        <!-- 配置访问首页的视图控制 -->
        <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
    
        <!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
        <bean id="multipartResolver"
              class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        </bean>
    
    </beans>
  2. 设置jdbc.properties配置文件作为Spring配置文件的Druid数据源的配置,里面写的是mysql的驱动、url地址、用户名和密码
    #驱动
    jdbc.driver=com.mysql.cj.jdbc.Driver
    #mysql地址
    jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
    #用户名和密码
    jdbc.username=root
    jdbc.password=root
  3. 通过Spring的核心配置文件搭建spring的框架,里面有他容器管理的组件,组件扫描、引入jdbc.properties 配置Druid数据源(对象)
    <?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="com.atguigu.ssm">
            <!--排除扫描控制层组件-->
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
        <!-- 引入jdbc.properties作为下面Druid数据源的KV值 -->
        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
        <!-- 配置Druid数据源(对象),交给spring容器管理,后面spring整合mybatis时可以让mybatis使用数据源对象 -->
        <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>
    
        
    
    </beans>
  4. 在 src\main\webapp\WEB-INF\templates\index.html 创建首页页面
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <h1>首页</h1>
    </body>
    </html>
  5. 创建控制层的请求控制器
    src\main\java\com\atguigu\ssm\controller\EmployeeController.java,自动装配service层组件
    package com.atguigu.ssm.controller;
    
    import com.atguigu.ssm.service.EmployeeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    @Controller
    public class EmployeeController {
        @Autowired
        private EmployeeService employeeService;
    }
    
  6. 创建业务层的接口 src\main\java\com\atguigu\ssm\service\EmployeeService.java
    package com.atguigu.ssm.service;
    
    public interface EmployeeService {
    }
    
  7. 创建业务层接口的实现类 
    src\main\java\com\atguigu\ssm\service\impl\EmployeeServiceImpl.java
    package com.atguigu.ssm.service.impl;
    
    import org.springframework.stereotype.Service;
    import com.atguigu.ssm.service.EmployeeService;
    @Service
    public class EmployeeServiceImpl implements EmployeeService {
    }
    
  8. 配置Tomcat服务器
  9. 启动服务器看控制台没有报错

SSM整合Mybatis框架

  • (回顾)Mybatis最重要的就是核心配置文件和Mapping映射文件;还有一个Mybatis专属的日志配置,可以打印我们执行的sql语句、传输的参数、执行的结果(事务影响的行数)
  1. 创建Mybatis的配置文件(我的版本没有Mybatis的配置文件模板,所以只能手写) src\main\resources\mybatis-config.xml ,这个核心配置文件可以被spring核心配置文件的下面即将要设置的SqlSessionFactoryBean的Bean的属性设置代替,但是只设置了部分代替
    <?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>
    
        <!--
            MyBatis核心配置文件中,标签的顺序:
            properties?,settings?,typeAliases?,typeHandlers?,
            objectFactory?,objectWrapperFactory?,reflectorFactory?,
            plugins?,environments?,databaseIdProvider?,mappers?
        -->
    
        <!--引入properties文件,这里注释掉同样也是因为:
        数据源信息已经被spring核心配置文件取代,所以不用引入properties文件的数据源信息-->
    <!--    <properties resource="jdbc.properties"></properties>-->
    
        <!--全局配置-->
        <settings>
            <!--将数据库的下划线映射服务器java名称为驼峰-->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
    
        <!--配置类型别名包集合路径,这里注释掉的原因是:
        被spring核心配置文件的SqlSessionFactoryBean的Bean的属性typeAliasesPackage代替了-->
    <!--    <typeAliases>-->
    <!--        &lt;!&ndash;单个包路径&ndash;&gt;-->
    <!--        <package name="com.atguigu.ssm.pojo"/>-->
    <!--    </typeAliases>-->
    
        <!--
            environments:配置多个连接数据库的环境
            属性:
            default:设置默认使用的环境的id,也就是指定哪个数据库
            这里注释掉是因为Spring核心配置文件的Bean为:
            SqlSessionFactoryBean的属性dataSource和取代了
        -->
    <!--    <environments default="development">-->
    <!--        <environment id="development">-->
    <!--            &lt;!&ndash;事务管理器,也可以交给spring容器管理&ndash;&gt;-->
    <!--            <transactionManager type="JDBC"></transactionManager>-->
    <!--            <dataSource type="POOLED">-->
    <!--                <property name="driver" value="${jdbc.driver}"/>-->
    <!--                <property name="uri" value="${jdbc.driver}"/>-->
    <!--                <property name="username" value="${jdbc.username}"/>-->
    <!--                <property name="password" value="${jdbc.password}"/>-->
    <!--            </dataSource>-->
    <!--        </environment>-->
    <!--    </environments>-->
    
        <!--引入Mybatis映射文件的多个包集合,这里注释掉的原因:
        如果Mapper映射文件与Mapper接口路径一致,
        只不过一个放在resources,一个放在java.就不需要如下配置,
        但这个前提是spring配置文件设置了MapperScannerConfigurer这个Bean-->
    <!--    <mappers>-->
    <!--        <package name="com.atguigu.ssm.mapper"/>-->
    <!--    </mappers>-->
    
        <!--配置插件-->
        <plugins>
            <!--配置分页插件-->
            <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
        </plugins>
    
    </configuration>
  2. Mybatis是面向接口执行SQL语句的,所以要创建持久层的接口 
    src\main\java\com\atguigu\ssm\mapping\EmployeeMapper.java ,这个接口不需要添加注解,因为我们是通过Spring的配置文件的一个Bean(MapperScannerConfigurer)配置这个类的
    package com.atguigu.ssm.mapper;
    //这个接口不需要添加注解,因为我们是通过Spring的配置文件的一个Bean(MapperScannerConfigurer)配置这个类的
    public interface EmployeeMapper {
    }
    
  3. 创建POJO类 src\main\java\com\atguigu\ssm\pojo\Employee.java ,其set方法名要与数据库数据表字段一致,并具有遵循驼峰命名规则
    package com.atguigu.ssm.pojo;
    
    /**
     * 该类为POJO类,属性对应的set方法名要与数据库特定数据表字段一致,
     * 并且可以通过在Mybatis核心配置文件设置驼峰命名规则,
     * 以下设置了含参无惨构造、get、set方法、toString方法
     */
    public class Employee {
        private Integer empId;
        private String empName;
        private Integer age;
        private String gender;
        private String email;
    
        public Employee() {
        }
    
        public Employee(Integer empId, String empName, Integer age, String gender, String email) {
            this.empId = empId;
            this.empName = empName;
            this.age = age;
            this.gender = gender;
            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 getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        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 +
                    ", gender='" + gender + '\'' +
                    ", email='" + email + '\'' +
                    '}';
        }
    }
    
  4. Mapper接口创建完后,我们需要与Mapper接口对应的映射文件 src\main\resources\com\atguigu\ssm\mapper\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接口一致-->
    <mapper namespace="com.atguigu.ssm.mapper.EmployeeMapper">
    
    
    </mapper>
  5. 在spring配置文件中配置Bean,分别为SqlSessionFactory和SqlSession,交给springIOC容器管理。这样就不用每次操作Mybatis,就要先加载核心配置文件,获取一个SqlSessionFactoryBuilder,然后通过这个SqlSessionFactoryBuilder创建一个SqlSessionFactory,然后在通过SqlSessionFactory创建一个SqlSession对象,再要通过SqlSession获取Mapper接口(例如上面的:EmployeeMapper.java)并创建Mapper接口的代理实现类对象才能执行Mapper接口的方法执行sql语句、或者mapper映射文件上的sql语句
    <?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="com.atguigu.ssm">
            <!--排除扫描控制层组件-->
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
        <!-- 引入jdbc.properties作为下面Druid数据源的KV值 -->
        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
        <!-- 配置Druid数据源(对象),交给spring容器管理,后面spring整合mybatis时可以让mybatis使用数据源对象 -->
        <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>
    
        <!-- 配置由Mybatis-Spring包提供的对象,
        该SqlSessionFactoryBean是用于创建SqlSessionFactory这个Bean的工厂,
        然后将SqlSessionFactory交给springIOC容器,省略掉先获取SqlSessionFactoryBean再创建SqlSessionFactory,
        是通过SqlSessionFactoryBean的getObject()方法实现的-->
        <bean class="org.mybatis.spring.SqlSessionFactoryBean">
            <!--设置SqlSessionFactoryBean,里面的属性可以代替Mybatis核心配置文件,也可以配置mybatis核心配置文件然后这里指向他-->
            <!-- 通过设置MyBatis配置文件的路径,之前怎么手动配置的在spring封装后也怎么配置 -->
            <property name="configLocation" value="classpath:mybatis-config.xml"></property>
            <!-- 设置数据源,这个数据源可以在Mybatis核心配置中设置,也可以在这里通过ref引用id为dataSource的数据源信息,
             那么Mybatis核心配置文件就不需要写数据源信息了-->
            <property name="dataSource" ref="dataSource"></property>
            <!-- 设置类型别名所对应的包 -->
            <property name="typeAliasesPackage" value="com.atguigu.ssm.pojo"></property>
            <!--设置映射文件的路径,"*"表示任意,这里注释掉的原因:
            若映射文件所在路径和mapper接口所在路径一致,则不需要设置,
            如果不一致,就需要重新设置映射文件路径
            但这个前提是设置了MapperScannerConfigurer这个Bean-->
            <!--<property name="mapperLocations" value="classpath:mapper/*.xml"></property>-->
        </bean>
    
        <!--
            spring整合Mybatis时简化Mybatis用到的一个类MapperScannerConfigurer
            配置mapper接口的扫描配置,由mybatis-spring提供,
            可以将指定包下所有的mapper接口,
            通过上面的Bean(SqlSessionFactoryBean创建的SqlSessionFactory创建的sqlSession)来为接口创建动态代理
            并将这些动态代理作为IOC容器的bean管理,这样的话我们直接在Service层直接自动装配Mapper接口的动态代理对象即可.
            这个路径也可以算是Mapper映射文件的包,也可以算是Mapper接口的包,
            否则就要设置<property name="mapperLocations" value="">这个标签,
            或者Mybatis核心配置文件的 <mappers><package name="com.atguigu.ssm.mapper"/></mappers>这个标签,
            这也是为什么推荐Mapper映射文件所在路径和mapper接口所在路径要一致原因,
            且加上spring整合Mybatis时简化Mybatis用到的一个类MapperScannerConfigurer这个,
            可以减少很多的配置
        -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.atguigu.ssm.mapper"></property>
        </bean>
    
    
    </beans>
  6. 在固定的位置上添加固定的文件名的文件 src\main\resources\log4j.xml ,用于添加log4j日志功能,这个日志可以打印我们执行的sql语句、传输的参数、执行的结果(事务影响的行数)
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <!--idea提示xmlns:log4j="http://jakarta.apache.org/log4j/"爆红是没事的-->
    <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>

SSM整合事务

  • 回顾:配置声明式事务有两种方式,一种是通过xml方式,一种是通过注解方式(用得比较多),本次我们使用注解方式。因此我们需要配置事务管理器、还有开启事务注解驱动
  1. 在Spring核心配置文件中添加如下配置,用于配置事务管理器和开启事务注解驱动,这样我们就可以通过注解方式实现事务管理,这也意味着我们Service可以自动装配Dao层的组件(mapper接口对应的代理实现类)
        <!--配置事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!--基于连接对象进行操作,连接对象是数据源管理的,因此我们要引入数据源-->
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    
        <!--开启事务注解驱动,然后通过id引用上面的事务管理器,如果事务管理器id就是transactionManager,
        可以不用该配置,但是建议还是加上可以给其他用户更加直观的表现.
        然后该标签的功能就是使用注解@Transactional标识的方法和类进行事务管理-->
        <tx:annotation-driven transaction-manager="transactionManager"/>
    
  2. mybatis辅助插件,可选可不选安装,安装好需要重启,可以将Mapper接口的方法快速定位到mapper映射文件xml文件的指定sql语句位置(当然这个插件还有其他功能例如代码提示自动补齐等可以用)

(实践)SSM整合实现页面展示所有员工信息

  1. 编辑Mapper映射文件,添加sql语句,该sql与之对应的是类com.atguigu.ssm.mapper.EmployeeMapper对应的方法getAllEmployee
    <?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接口一致-->
    <mapper namespace="com.atguigu.ssm.mapper.EmployeeMapper">
    
        <!--执行查询操作,id为对应mapper接口的方法名;
        resultType为sql查询回来的结果用什么类型对象接收,值为类的全类名,
        作为mapper接口的方法的返回值;内容为sql语句-->
        <select id="getAllEmployee" resultType="com.atguigu.ssm.pojo.Employee">
            select * from t_emp
        </select>
    
    </mapper>
  2. 在Mapper接口 src\main\java\com\atguigu\ssm\mapper\EmployeeMapper.java 中配置与Mapper映射文件对应的抽象方法,配置完后会有插件提示
  3. 配置Service层接口 src\main\java\com\atguigu\ssm\service\EmployeeService.java 
    package com.atguigu.ssm.service;
    
    import com.atguigu.ssm.pojo.Employee;
    
    import java.util.List;
    
    public interface EmployeeService {
        /**
         * 查询所有的员工信息
         * @return
         */
        List<Employee> getAllEmployee();
    }
    
  4. 配置配置接口实现类 src\main\java\com\atguigu\ssm\service\impl\EmployeeServiceImpl.java ,因为Spring核心配置文件配置了事务管理器和事务扫描,因此可以通过注解实现Service层自动装配Dao层
    package com.atguigu.ssm.service.impl;
    
    import com.atguigu.ssm.mapper.EmployeeMapper;
    import com.atguigu.ssm.pojo.Employee;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import com.atguigu.ssm.service.EmployeeService;
    
    import java.util.List;
    
    @Service
    public class EmployeeServiceImpl implements EmployeeService {
    
        //因为Spring核心配置文件配置了事务管理器和事务扫描,因此可以通过注解实现Service层自动装配Dao层
        @Autowired
        private EmployeeMapper employeeMapper;
    
        public List<Employee> getAllEmployee() {
            return employeeMapper.getAllEmployee();
        }
    }
    
  5. 编辑请求控制器,添加如下方法,处理浏览器想要获取员工所有信息展示到员工列表页面中
        /**
         * 处理浏览器想要获取员工所有信息展示到员工列表页面中
         * @param model
         * @return
         */
        @GetMapping("/employee")
        public String getAllEmployee(Model model){
            //通过数据库查询所有的员工信息
            List<Employee> list = employeeService.getAllEmployee();
            //将员工信息存到模型对象中
            model.addAttribute("list",list);
            //设置视图名称一会用于渲染
            return "employee_list";
        }
    
  6. 编辑首页页面 E:\StudyProject\SSM\ssm\src\main\webapp\WEB-INF\templates\index.html ,设置跳转到员工列表的超链接
    <a th:href="@{/employee}">查询所有的员工信息</a>
    
  7. 添加员工列表页面 src\main\webapp\WEB-INF\templates\employee_list.html ,通过请求域中获取员工信息数据遍历到页面进行展示,修改和删除操作暂时做留作拓展
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>员工列表</title>
        <!--关联一个样式表,但是我没有,练习代码没有提供,因此不用,但是写出保留-->
    <!--    <link rel="stylesheet" th:href="@{/static/css/index_work.css}"-->
    </head>
    <body>
        <table>
            <tr>
                <th>员工列表</th>
            </tr>
            <tr>
                <!--这个流水号不是id,是当前页面展示多少条数据,然后赋予的从1开始的好嘛-->
                <th>流水号</th>
                <th>员工姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            <!--将request请求域中的Key为"list"的集合对象里面的数据全部迭代出来放到employee对象中,
            还有一个内置的循环状态对象status,这个对象也是由Thymeleaf提供的-->
            <tr th:each="employee,status : ${list}">
                <!--循环状态对象status里面有属性,属性count就是集合循环执行的第几次-->
                <td th:text="${status.count}"></td>
                <!--后面就是员工的信息-->
                <td th:text="${employee.empName}"></td>
                <td th:text="${employee.age}"></td>
                <td th:text="${employee.gender}"></td>
                <td th:text="${employee.email}"></td>
                <td><a href="">修改</a><a href="">删除</a></td>
            </tr>
        </table>
    </body>
    </html>
  8. 重启服务器测试效果,发现员工信息被正常展示出来

(实践)SSM整合实现页面通过分页方式展示所有员工信息,并设置分页跳转的超链接

  • 通过之前在Mybatis的核心配置文件配置的分页插件,因此我们可以Mybatis的分页对象实现更便捷的方式操作查询所有的Mybatis的查询功能获取分页后的信息
  • 在分页功能中,当我们有上一页的时候才展示首页和上一页的分页页面跳转超链接。同理,在有下一页的时候才展示下一页和末页分页页面跳转超链接。还有分页导航(例如我分页导航设置的是5页,但是我一共就6页,而且我当前浏览的是第5页,因此只需要展示2、3、4、5、6即可,然后把当前访问的页码的分页导航标识出来),同样可以通过Mybatis的分页对象实现
  1. 修改Service层接口src\main\java\com\atguigu\ssm\service\EmployeeService.java

    package com.atguigu.ssm.service;
    
    import com.atguigu.ssm.pojo.Employee;
    import com.github.pagehelper.PageInfo;
    
    import java.util.List;
    
    public interface EmployeeService {
        /**
         * 查询分页后所有的员工信息
         * @return
         */
        PageInfo<Employee> getAllEmployee(Integer pageNum);
    
    
    }
    
  2. 修改Service层接口实现类 src\main\java\com\atguigu\ssm\service\impl\EmployeeServiceImpl.java ,通过分页插件的静态资源对象来实现设置查询几页,一页多少行数据,分页导航设置也多少个

    package com.atguigu.ssm.service.impl;
    
    import com.atguigu.ssm.mapper.EmployeeMapper;
    import com.atguigu.ssm.pojo.Employee;
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import com.atguigu.ssm.service.EmployeeService;
    
    import java.util.List;
    
    
    @Service
    public class EmployeeServiceImpl implements EmployeeService {
    
        //因为Spring核心配置文件配置了事务管理器和事务扫描,因此可以通过注解实现Service层自动装配Dao层
        @Autowired
        private EmployeeMapper employeeMapper;
    
    
        public PageInfo<Employee> getAllEmployee(Integer pageNum) {
            //在查询员工信息的时候开启分页功能,该方法的形参是查询第几页(灵活),一页展示多少条数据(写死)
            PageHelper.startPage(pageNum,4);
            //根据上面分页功能的设置,查询分页后指定页数的所有的员工信息,查询功能受上面的分页功能限制(类似被拦截了一样)
            List<Employee> list = employeeMapper.getAllEmployee();
            System.out.println(list);//打印查看
            //将集合放到新建的PageInfo对象中,通过含参构造方法的第二个参数设置导航分页(比如设置了导航分页为3,当前查看的页数是2,那就会显示1,2,3)
            PageInfo<Employee> page = new PageInfo(list, 5);
            //然后返回pageInfo对象
            return page;
        }
    }
    
  3. 修改请求控制器 src\main\java\com\atguigu\ssm\controller\EmployeeController.java ,获取分页数据之后存放员工信息到模型对象中然后返回视图名称

    package com.atguigu.ssm.controller;
    
    import com.atguigu.ssm.pojo.Employee;
    import com.atguigu.ssm.service.EmployeeService;
    import com.github.pagehelper.PageInfo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    import java.util.List;
    
    @Controller
    public class EmployeeController {
        @Autowired
        private EmployeeService employeeService;
    
        /**
         * 处理浏览器想要获取员工所有信息展示到员工列表页面中,并分页
         * @param pageNum 查看第几页
         * @param model
         * @return
         */
        @GetMapping("/employee/page/{pageNum}")
        public String getAllEmployee(@PathVariable("pageNum")Integer pageNum,
                                     Model model){
            //通过数据库查询分页后的员工信息集合
            PageInfo<Employee> page = employeeService.getAllEmployee(pageNum);
            //将分页员工信息存到模型对象中
            model.addAttribute("page",page);
            //设置视图名称一会用于渲染
            return "employee_list";
        }
    }
    
  4. 修改首页页面 E:\StudyProject\SSM\ssm\src\main\webapp\WEB-INF\templates\index.html ,因为有了分页选项,因此首页发送的应该是员工列表分页后的第一页的所有员工信息请求

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <h1>首页</h1>
    <a th:href="@{/employee/page/1}">查询第一页的所有的员工信息</a>
    </body>
    </html>
  5. 编辑员工页面 E:\StudyProject\SSM\ssm\src\main\webapp\WEB-INF\templates\employee_list.html ,将员工信息根据分页展示出来,并设置分页导航展示

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>员工列表</title>
        <!--关联一个样式表,但是我没有,练习代码没有提供,因此不用,但是写出保留-->
    <!--    <link rel="stylesheet" th:href="@{/static/css/index_work.css}"-->
    </head>
    <body>
        <table>
            <tr>
                <th>员工列表</th>
            </tr>
            <tr>
                <!--这个流水号不是id,是当前页面展示多少条数据,然后赋予的从1开始的好嘛-->
                <th>流水号</th>
                <th>员工姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            <!--将request请求域中的Key为"page"的集合对象里面的list里面的数据全部迭代出来放到employee对象中,
            还有一个内置的循环状态对象status,这个对象也是由Thymeleaf提供的-->
            <tr th:each="employee,status : ${page.list}">
                <!--循环状态对象status里面有属性,属性count就是集合循环执行的第几次-->
                <td th:text="${status.count}"></td>
                <!--后面就是员工的信息-->
                <td th:text="${employee.empName}"></td>
                <td th:text="${employee.age}"></td>
                <td th:text="${employee.gender}"></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="${page.hasPreviousPage}" th:href="@{/employee/page/1}">首页</a>
            <!--通过如下拼接方式拼接上一页的页码实现上一页超连接-->
            <a th:if="${page.hasPreviousPage}" th:href="@{'/employee/page/'+${page.prePage}}">上一页</a>
            <!--将数组里面的导航分页页码遍历提取出来,并设置超链接-->
            <span th:each="num : ${page.navigatepageNums}">
                <!--把当前访问的页码的分页导航标识出来,设置与别的分页导航不一样的红颜色,并通过拼接方式让他加上中括号-->
                <a th:if="${page.pageNum == num}" style="color: crimson" th:href="@{'/employee/page/'+${num}}" th:text="'['+${num}+']'"/>
                <!--不是当前访问的页码的分页导航就普通展示-->
                <a th:if="${page.pageNum != num}" th:href="@{'/employee/page/'+${num}}" th:text="${num}"/>
            </span>
            <!--在有下一页的时候才展示下一页和末页分页页面跳转超链接-->
            <!--通过如下拼接方式拼接下一页页码实现下一页超连接-->
            <a th:if="${page.hasNextPage}" th:href="@{'/employee/page/'+${page.nextPage}}">下一页</a>
            <!--通过如下拼接方式拼总页数页码实现末页超连接-->
            <a th:if="${page.hasNextPage}" th:href="@{'/employee/page/'+${page.pages}}">末页</a>
        </div>
    </body>
    </html>
  6. 重启服务器,演示效果

  7. 修改删除和操作就不演示了,可以参考之前高并发项目或者SpringMVC学习的通过Map集合模拟Dao层的演示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值