最通俗易懂的ssm框架整合讲解

环境

  • MySQL 8.0.16

1 Mybatis

1.1 数据库配置文件

jdbc.driver=com.mysql.cj.jdbc.Driver
# 如果使用mysql 6+,增加一个时区的配置
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=123456

com.mysql.jdbc.Driver 与 com.mysql.cj.jdbc.Driver ?

  • com.mysql.jdbc.Driver 是 mysql-connector-java 5 中的
  • com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6 中的

JDBC 连接 mysql 5:

url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false

JDBC 连接 mysql 6:

url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&?useUnicode=true&characterEncoding=utf8&useSSL=false

1.2 配置 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>
    <!--配置数据源,交给 spring 去做-->
    <typeAliases>
        <package name="com.fyy.pojo"/>
    </typeAliases>

    <mappers>
        <mapper class="com.fyy.dao.BookMapper"/>
    </mappers>
</configuration>

typeAiases 标签作用?

其中,<typeAiases>标签的作用只是为 Java 类型指定一个短的名字,它只和xml 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

指定一个包名,Mybatis 会在此包名下搜索需要的 Java Bean,每一个在此包下的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名作为它的别名,比如:com.fyy.pojo.User 的别名为:user ,若有注解,则别名为其注解值。如下例子:

@Alias("hello")
public class Hello(){
    
    }

mappers标签作用?

Mybatis 是基于 Sql 映射配置的框架,Sql 语句在Mapper 配置文件中,当构建 SqlSession 类之后,就需要去读取 Mapper 配置文件中的 sql 配置。

mappers : 映射器,以最佳的方式告诉 Mybatis 去哪里找映射文件,就是用来配置需要加载的 sql 映射配置文件路径的。

mappers 下的每一个 mapper 都是一个mapper,配置的都是一个独立的映射配置文件的路径,配置方式有以下几种。

1、接口所在包

<mappers>
	<!-- mapper接口所在的包名 -->
	 <package name="com.fyy.mapper"/>
</mappers>

# package标签,通过 name 属性指定 mapper 接口所在的包名,此时对应的映射文件必须
与接口位于同一路径下,并且名称相同。

2、相对路径配置

<mappers>
   	<mapper resource="com/fyy/mapper/FlowerMapper.xml"/>
</mappers>


# mapper标签,通过 resource 属性引入 classpath 路径的相对资源

3、类注册引入

<mappers>
  	<mapper class="com.fyy.mapper.FlowerMapper"/>
</mappers>

# mapper 标签,通过 class 属性指定 mapper 接口名称,此时对应的映射文件必须与接口位于同一路径
下,并且名称相同

4、使用 url 绝对路径方式引入(不推荐)

<mappers>
	<mapper url="file:///var/mappers/UserMapper.xml"/>
</mappers>

# mapper 标签,通过 url 引入网络资源或者本地磁盘资源

总结

只有配置了 mappers 信息,Mybatis 才知道去哪里加载 Mapper 配置文件,开发中,根据项目中 Mapper 的配置偏好,选择整合配置文件的配置方式。


2 Spring 整合 Mybatis

2.1 Spring 整合 dao 层

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--    配置整合Mybatis-->
    <!--1、关联数据库配置文件-->
    <context:property-placeholder location="classpath:database.properties"/>

    <!--2、连接池-->
    <!--数据库连接池
    dbcp 半自动化操作 不能自动连接
    c3p0 自动化操作(自动的加载配置文件 并且设置到对象里面)-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 配置连接池属性 -->
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- c3p0连接池的私有属性 -->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>
        <!-- 关闭连接后不自动commit -->
        <property name="autoCommitOnClose" value="false"/>
        <!-- 获取连接超时时间 -->
        <property name="checkoutTimeout" value="10000"/>
        <!-- 当获取连接失败重试次数 -->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>

    <!-- 3.配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 给出需要扫描Dao接口包 -->
        <property name="basePackage" value="com.fyy.dao"/>
    </bean>
</beans>

2.1.1 context:property-placeholder标签作用?

在开发中有些参数是常量,比如:连接数据库的 url,password,username 等信息,不需要常变化,但在不同阶段又需要变化,有没有有一种方案方便我们在一个阶段内不需要频繁写一个参数的值,但在不同阶段间又可以方便的切换参数的配置信息。

解决方案:Spring 3 中提供了一种简便的方式就是 content:property-placeholder元素,即可解决上述问题。

在 content:property-placeholder 标签中 利用属性 localtion ,值为文件路径,可以使用 classpath: 指定文件名即可。这里我们关联上数据库配置信息。

Spring 容器中仅允许最多定义一个 context:property-placeholder ,其余的会被忽略。

2.1.2 数据库连接池

每次创建一个数据库连接都是一次极大的资源消费,所以连接复用,通过建立一个数据库连接池以及一套连接使用管理策略,可以使一个数据库连接可以得到高效、安全的复用,能避免了数据库连接池频繁建立、关闭的开销。

连接池的本质:介于 Java 和 JDBC 之间的 Java jar 包!

第1步中,我们关联了数据库配置信息,利用 bean 标签可获取其中的配置信息。

可根据项目实际开发中,配置连接池的最大数量、最小数量、关闭连接后是否自动 commit、获取连接超时时间、获取连接失败重试次数等,很多属性,在这不一 一赘述了。

2.1.3 配置 SqlSessionFactory 对象

SqlSessionFacoty 的作用就是创建 SqlSession,SqlSession 就是一个会话,相当于 JDBC 中的 Connection 对象,每次应用访问数据库,就要通过 SqlSessionFactory 创建 SqlSession ,所以 SqlSessionFacoty 应该在 Mybatis 整个生命周期中,每一个数据库只应该对应一个 SqlSessionFacoty.

SqlSessionFacoty 在整个 Mybatis 运行流程中的作用如下图。
在这里插入图片描述
配置 SqlSessionFactory 对象时,将数据库连接池注入到其中,再配置 mybatis 全局配置文件 。
我的理解是:在 SqlSessionFactory 创建 SqlSession 连接数据库时,需要知道数据库连接池的信息,以及数据源。

2.1.4 配置扫描dao接口包

MapperScannerConfigurer 自动扫描将 Mapper 接口生成代理注入到 Spring容器,Mybatis 在与 Spring 整合的时候配置 MapperFactoryBean 来生成 Mapper 接口的代理。 basePackage 属性是让你为映射器接口文件设置基本的包路径,你可以使用分号或者逗号作为分隔符设置多余一个包的路径,每个映射器将会在指定的包路径中递归的被搜索到。 注意,没有必要去指定 SqlSessionFactory 或 SqlSessionTemplate,因为 MapperScannerConfigurer 将会创建 MapperFactoryBean,之后自动装配,但如果使用了一个以上的 DataSource,那么自动装配可能会失效。这种情况下,可以使用 sqlSessionFactoryBeanName 或 sqlSessionTemplateBeanName 属性来设置正确的 bean 名称来使用。

大白话理解:扫描dao层的接口,MapperScannerConfigurer 会自动为每个接口生成一个 接口代理,这个接口代理是接口的实现类,并注入到Spring容器中。

2.2 Spring 整合 service 层

<?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
   http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 扫描service相关的bean -->
    <context:component-scan base-package="com.fyy.service" />

    <!--BookServiceImpl注入到IOC容器中-->
    <bean id="BookServiceImpl" class="com.fyy.service.BookServiceImpl">
        <property name="bookMapper" ref="bookMapper"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

事务管理器:DataSourceTransactionManager

事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编码式和声明式的两种方式。编程式事务指的是通过编码方式实现事务;声明式事务基于 AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中声明式事务用的比较多。声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于 @Transactional 注解的方式。

其中 配置文件声明事务,是将数据库连接池注入到 事务管理器中。关于注解方式声明事务,就不在这里做过多介绍,后期会单独拿出来分享Spring事务。


3 整合 SpringMVC

web.xml 配置文件

3.1 web.xml 文件是如何执行的?

3.1.1 执行顺序

访问顺序为:1->2->3->4,其中 2 和 3 的值必须相同。

url-pattern标签代表当一个请求发送到 servlet 容器时,容器会先将请求的 url 减去 当前应用上下文的路径作为 servlet 的映射 url,比如我访问的是 http://localhost/test/aaa.html,我的应用上下文是 test,容器会将 http://localhost/test 去掉,剩下的 /aaa.html 部分拿来做 servlet 映射匹配。如果与 设置的 url-pattern 映射匹配成功,请求才会被 DispatcherServlet 处理。图中的 <url-pattern> 中的值为:/,代表所有请求都会被处理。

而被DispatcherServlet 处理前,还会经过 2 ,3 步骤,url 匹配成功后,这个 url 访问名为 servlet-name 中值的 servlet,两个 servlet-name 值必须相同,因为 servlet 标签中的 servlet-name 标签映射到 servlet-class 标签中的值,最终访问 servlet-class 标签中的 DispatcherServlet 类,此时,请求才会被 DispatcherServlet 处理。

3.1.2 init-param标签

图中 \标签中的 \标签作用是,设置 springmvc 配置文件位置以及名称,springmvc配置文件不设置默认位置是:webapp,可以使用 classpath 设置文件的名称为:spring-mvc.xml ,代表 springmvc 配置文件名必须为 spring-mvc.xml,如不使用 classpath 设置其路径及名称,默认在 webapp下,名称为:\标签中的值 + "-servlet.xml",例如:如 标签中值为:springmvc,则默认的 springmvc 配置文件名为:springmvc-servlet.xml

3.1.3 load-on-startup标签

图中 \标签作用是,设置 servlet加载时间,如不设置默认在第一次请求访问时加载 servlet,若设置此标签值为正整数,会将 servlet 的加载时间提前到项目启动时,此标签中可以写整数,但写负整数和0和没有设置是一样的效果,只有设置为正整数才会将 servlet 的加载时间提前到项目启动时,也就是 tomcat 启动时,值越小,代表优先级越高。

3.2 springmvc 配置文件是如何执行的?

spring-mvc.xml 配置文件

3.2.1 mvc:annotation-driven作用?

springmvc注解驱动会自动注册:DefaultAnnotationHandlerMapping 与 AnnotationMethodHandlerAdapter 两个bean,这两个 bean 是 SpringMVC 为 @Controller 分发请求所必须的,解决了使用 @Controller 注解的前提配置。

在 Spring MVC 3.1 以上:

  • DefaultAnnotationHandlerMapping 变更为:RequestMappingHandlerMapping
  • AnnotationMethodHandlerAdapter 变更为:RequestMappingHandlerAdapter
通常如果我们希望通过注解的方式来进行 SpringMVC开发,我们会在 springmvc 配置文件中使用 注解驱动:\,那这个标签做了什么?通过寻找源码,找到注解驱动的实现类是:org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser

我们来看看这个类主要做了什么工作?

AnnotationDrivenBeanDefinitionParser类向工厂中注册了几个 bean 实例,其中包括:

  • RequestMappingHandlerMapping
  • BeanNameUrlHandlerMapping
  • RequestMappingHandlerAdapter
  • HttpRequestHandlerAdapter
  • SimpleControllerHandlerAdapter
  • ExceptionHandlerExceptionResolver
  • ResponseStatusExceptionResolver
  • DefaultHandlerExceptionResolver

上面的bean实例都是做什么的呢?

前两个 bean 是 HandlerMapping 接口的实现类,用来处理请求映射的。其中第一个处理是 @RequestMapping 注解的,第二个是将 controller 类的名字映射为 请求 url,中间三个 adpter 是用来处理请求的,具体说就是确定调用哪个 controller 的哪个方法来处理当前请求,第一个处理 @Controller 注解的处理器,支持自定义方法参数和返回值,第二个是处理继承 HttpRequestHandler 的处理器,第三个处理继承自 Controller 接口的处理器,后面三个是用来处理异常的解析器。

结论

如果使用@Controller 注解,没有配置注解驱动: <mvc:annotation-driven> 的话,那么所有的请求都无法找到 DispatcherServlet ,并无法把请求分发至控制器。添加注解驱动后,才会扫描所有带有 @Controller 注解的类,由 spring 管理并维护。

3.2.2 mvc:default-servlet-handler作用?

还记得我们在 web.xml 中配置了 url-pattern,用来过滤请求,SpringMVC 将接收到的所有请求都看做是一个普通请求,包括对于静态资源的请求,这样一来,所有对于静态资源的请求都会被看做是一个普通的后台控制器请求,而静态资源的请求会因为找不到资源而报404异常。查看 tomcat 日志就可以看到会有警告。

在这里插入图片描述

对于此问题 SpringMVC 在全局配置文件中提供了一个 <mvc:default-servlet-handler>标签,在 web 容器启动的时候会在上下文中定义一个 DefaultServletHttpRequestHandler ,它会对 DispatcherServlet 请求进行处理,如果该请求已经做了映射,那么会接着交给后台对应的处理程序,如果没有映射,就交给 web 应用服务器默认的 servlet 处理,从而找到对应的静态资源,只有找不到静态资源时会报错。

如果默认的 Servlet 容器不用默认的 default ,用不同名称进行自定义配置,或者在缺省 Servlet 名称未知的情况下使用了不同的 Servlet 容器,则必须显示提供默认 Servlet 的名称。

<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>

3.2.3 context:component-scan 作用?

扫描组件,将所有使用 @Controller 注解的类作为 SpringMVC 的控制层。其中 base-package 属性是指定扫描的包。

3.2.4 视图解析器 作用?

视图解析器,是将 prefix + 视图名称 + suffix = 确定最终要跳转的页面,其中视图名称是什么?? 处理请求的方法会返回一个字符串,这个字符串即视图名称,最终会通过配置文件中配置的视图解析器实现页面的跳转。例如:
@Controller
public class TestController {
    
    
    @RequestMapping("hello")
    public String hello() {
    
    
        System.out.println("success");
        return "success";
    }
}

# 其中返回字符串为:success,所以处理此请求最终要跳转的页面为:/WEB-INF/view/success.jsp

关于 SpringMVC的讲解可以查看小编的另一篇文章。SpringMVC从基础到源码


4 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath:spirng/spring-dao.xml"/>
    <import resource="classpath:spirng/spring-service.xml"/>
    <import resource="classpath:spirng/spring-mvc.xml"/>
</beans>
applicationContext.xml,Spring 的核心配置文件,也可以通过配置文件修改名称。 什么时候读取配置文件,当我们在客户端新建 ApplicationContext 实例时,会加载此配置文件,其中常用的 ApplicationContext 实现类有:
  • ClassPathXmlApplicationContext
  • ClassPathResource
  • XmlWebApplicationContext
  • FileSystemXmlApplicationContext
其中 \ 是将多个配置文件通过导入的方式整合,让配置信息更清晰,达到了解耦的效果。

结束

以上就是本人学习ssm框架配置的总结,有的地方不够深入,但对于初学者来说应该也会收获颇丰,如有错误,还请大佬们指正!

猜你喜欢

转载自blog.csdn.net/weixin_42653522/article/details/108624967
今日推荐