SSM框架整合是将Spring、Spring MVC和MyBatis三个独立的Java企业级开发框架无缝地集成在一起,形成一个功能强大、层次清晰、易于维护的全栈Web应用开发解决方案。其核心目标是利用Spring的IoC容器管理所有Bean的生命周期和依赖关系,使用Spring MVC处理Web层请求,并通过MyBatis完成数据持久化操作。
一、核心框架职责与整合原理
| 框架名称 | 核心职责 | 在整合中的角色 |
|---|---|---|
| Spring | 提供IoC(控制反转)容器和AOP(面向切面编程)支持,管理业务逻辑层(Service)和数据访问层(DAO)的Bean,并负责事务管理。 | 作为整合的“粘合剂”和“大脑”,通过配置文件或注解创建并管理所有Bean,将Spring MVC和MyBatis的组件纳入统一管理。 |
| Spring MVC | 基于MVC设计模式,负责处理Web层的HTTP请求和响应,包括请求分发、参数绑定、视图解析等。 | 作为Web表现层,其核心控制器DispatcherServlet由Spring IoC容器初始化,并负责调用后端的Service层。 |
| MyBatis | 一个半自动化的ORM框架,负责数据库交互,将Java对象与SQL语句进行映射,简化JDBC操作。 | 作为数据持久层,其SqlSessionFactory和Mapper接口代理对象由Spring容器创建和管理,从而实现与业务逻辑层的解耦。 |
整合原理:整个整合过程围绕Spring的IoC容器展开。通过配置,将MyBatis的SqlSessionFactory、Mapper扫描器以及Spring MVC的DispatcherServlet等关键组件都注册为Spring容器中的Bean。这样,Spring MVC的控制器(Controller)就可以直接注入(@Autowired)Service层的Bean,而Service层的Bean又可以注入由MyBatis动态生成的Mapper接口实现,从而打通从Web请求到数据库操作的完整链路。
二、项目结构与关键配置详解
一个典型的SSM整合项目目录结构如下(基于Maven):
ssm-demo ├── src/main/java │ └── com.example │ ├── controller # 控制层 (Spring MVC) │ ├── service # 业务逻辑层接口 │ │ └── impl # 业务逻辑层实现 │ ├── dao # 数据访问层接口 (MyBatis Mapper) │ └── entity # 实体类 (POJO) ├── src/main/resources │ ├── spring # Spring配置文件 │ │ ├── applicationContext.xml # 核心Spring配置 │ │ └── spring-mvc.xml # Spring MVC配置 │ ├── mybatis # MyBatis配置文件 │ │ ├── mybatis-config.xml # MyBatis全局配置 │ │ └── mapper/*.xml # SQL映射文件 │ └── jdbc.properties # 数据库连接属性文件 ├── webapp │ └── WEB-INF │ └── web.xml # Web应用部署描述符 └── pom.xml # Maven依赖管理1. Maven依赖配置 (pom.xml)
整合的基础是引入必要的依赖。以下为关键依赖示例:
<dependencies> <!-- Spring 核心 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.23</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.23</version> </dependency> <!-- MyBatis 核心及与Spring整合包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.1.1</version> </dependency> <!-- 数据库驱动及连接池 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.18</version> </dependency> <!-- Servlet API --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies>2. Spring核心配置文件 (applicationContext.xml)
此文件负责整合业务层、持久层及事务。
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 1. 扫描Service层组件 --> <context:component-scan base-package="com.example.service"/> <!-- 2. 加载数据库属性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 3. 配置数据源 (使用Druid) --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 4. 配置SqlSessionFactory, 将MyBatis与Spring连接 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 指定MyBatis全局配置文件位置 --> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/> <!-- 指定SQL映射文件位置,可使用通配符 --> <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/> </bean> <!-- 5. 配置Mapper扫描器,自动为DAO接口创建代理对象 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> <!-- 6. 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 开启注解驱动的事务管理 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>3. Spring MVC配置文件 (spring-mvc.xml)
此文件负责配置Web层。
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 1. 扫描Controller层组件 --> <context:component-scan base-package="com.example.controller"/> <!-- 2. 开启注解驱动,自动注册HandlerMapping, HandlerAdapter等 --> <mvc:annotation-driven/> <!-- 3. 静态资源处理,如图片、CSS、JS文件 --> <mvc:default-servlet-handler/> <!-- 4. 配置视图解析器 (JSP示例) --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 5. 配置文件上传解析器 (可选) --> <!-- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/> --> </beans>4. Web应用入口配置 (web.xml)
此文件配置Servlet容器,是整合的启动点。
<?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"> <!-- 1. 配置Spring上下文监听器,用于加载applicationContext.xml --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 2. 配置Spring MVC的核心控制器DispatcherServlet --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定Spring MVC配置文件位置 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-mvc.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> <!-- 3. 字符编码过滤器 --> <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> </web-app>三、核心代码层实现示例
以一个简单的用户查询功能为例,展示各层代码如何协作。
- 实体层 (
entity/User.java)
package com.example.entity; public class User { private Integer id; private String username; private String email; // 省略getter、setter和toString方法 }- 数据访问层 (
dao/UserMapper.java接口 和resources/mybatis/mapper/UserMapper.xml)
package com.example.dao; import com.example.entity.User; import java.util.List; public interface UserMapper { User selectUserById(Integer id); List<User> selectAllUsers(); }<?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="com.example.dao.UserMapper"> <select id="selectUserById" resultType="com.example.entity.User"> SELECT * FROM user WHERE id = #{id} </select> <select id="selectAllUsers" resultType="com.example.entity.User"> SELECT * FROM user </select> </mapper>- 业务逻辑层 (
service/UserService.java接口 和service/impl/UserServiceImpl.java)
package com.example.service; import com.example.entity.User; import java.util.List; public interface UserService { User getUserById(Integer id); List<User> getAllUsers(); }package com.example.service.impl; import com.example.dao.UserMapper; import com.example.entity.User; import com.example.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service // 声明为Spring管理的Service Bean @Transactional // 声明事务,方法内所有数据库操作作为一个事务 public class UserServiceImpl implements UserService { @Autowired // 自动注入MyBatis生成的Mapper代理对象 private UserMapper userMapper; @Override public User getUserById(Integer id) { return userMapper.selectUserById(id); } @Override public List<User> getAllUsers() { return userMapper.selectAllUsers(); } }- 控制层 (
controller/UserController.java)
package com.example.controller; import com.example.entity.User; import com.example.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller // 声明为Spring MVC的Controller public class UserController { @Autowired // 自动注入Service层Bean private UserService userService; @GetMapping("/user/{id}") @ResponseBody // 返回JSON数据 public User getUser(@PathVariable("id") Integer id) { return userService.getUserById(id); } @GetMapping("/users") @ResponseBody public List<User> getAllUsers() { return userService.getAllUsers(); } }四、整合高级特性与常见问题
分页插件整合:MyBatis常用的PageHelper分页插件可以轻松集成。在
applicationContext.xml的sqlSessionFactory配置中添加插件即可实现物理分页。<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <value> helperDialect=mysql reasonable=true </value> </property> </bean> </array> </property> </bean>在Service层使用:
PageHelper.startPage(pageNum, pageSize); // 紧跟查询语句之前 List<User> users = userMapper.selectAllUsers();常见问题排查:
- Bean创建失败:检查
applicationContext.xml中组件扫描的包路径是否正确,依赖注入的Bean是否存在于Spring容器中。 - 404错误:检查
web.xml中DispatcherServlet的URL映射,以及Controller的请求映射路径(@RequestMapping)是否正确。 - 数据库连接失败:检查
jdbc.properties文件中的连接参数、数据库驱动版本以及网络连通性。 - 事务不生效:确保在Spring配置中开启了注解驱动事务 (
<tx:annotation-driven/>),并且在Service实现类或方法上正确使用了@Transactional注解。
- Bean创建失败:检查
参考来源
- SSM框架整合【图文详解】
- 2022新版图文详解IDEA整合SSM框架(附源码)
- SSM框架整合实战项目Demo详解
- SSM 框架整合的核心理论知识详解
- SSM框架整合实战项目详解
- 【SSM进阶学习】详解SSM框架中的整合与分页