- 1WEB 基础HTTP / Browser / WebServer静态页面写死,人人看到一样
- 2Servlet手写 if-else 分发不可扩展,无生命周期/并发管理
- 3JSP:参数散字符串参数散成一堆 String,取值靠字段名硬记
- 3JSP:scriptlet 塞逻辑scriptlet 把逻辑塞进页面,代码与 HTML 糊在一起
- 3JavaBean:数据对象化对象全靠 new、层层硬依赖
- 4Spring IoCWeb 路由仍手写 web.xml/if-else、手动取参绑定,展示/业务/数据访问没分开
- 5MVC · SpringMVC数据在库里,访问是重复样板 + 拼串有注入风险
- 6MySQLJava 连库要手写五步,连接与资源管理全手动
- 7JDBCSQL 与 Java 混写、结果集逐行手映射、没有动态 SQL
- 8MyBatis四份配置 + web.xml 装配繁琐,部署要外部 Tomcat
- 9SpringBoot链尾 · 不考核
SSM 整合
SSM 整合
目标:理解 Spring + SpringMVC + MyBatis 三大框架如何整合成一个三层架构,掌握四配置文件的加载关系、数据源与事务管理(@Transactional),能读懂一个完整 SSM 工程。
本模块把前几章的框架拼起来:Spring 管业务层(IoC + 事务)、SpringMVC 管 Web 层、MyBatis 管持久层。以真实工程
GuestBookSSM为样板,拆解「浏览器 → DispatcherServlet → Controller → Service → Mapper → 数据库」的完整闭环与四配置文件的加载顺序。
一、三层架构总览
SSM 把系统分成三层,每个框架各管一层:
- 表现层(Web):SpringMVC——DispatcherServlet 分发、Controller 处理请求、ViewResolver 渲染视图;
- 业务层:Spring——IoC 容器装配 Bean、@Service 封装业务、@Transactional 管理事务;
- 持久层:MyBatis——@Mapper 接口 + XML 写 SQL、resultMap 映射结果集。
下面交互实验沿请求链走一遍,看每一层的职责与配置归属(对照 GuestBookSSM):
交互实验:SSM 三层架构总览(SSMArchitectureMap)
点「下一步」沿请求链走一遍,或点击任一层看它的职责与配置归属。对照真实工程 GuestBookSSM(web.xml / springmvc-servlet.xml / applicationContext.xml / WordMapper.xml)。
浏览器
职责:发起 HTTP 请求,接收渲染后的 HTML 响应
二、四配置文件如何加载
一个 SSM 工程由四个配置文件串起来,Tomcat 启动时按下面的顺序加载:
web.xml → applicationContext.xml → mybatis-config.xml → WordMapper.xml → springmvc-servlet.xml
- web.xml:注册 ContextLoaderListener(建 Spring 根容器)+ DispatcherServlet(建 Web 子容器);
- applicationContext.xml(根容器):dataSource / txManager / sqlSessionFactory / MapperScannerConfigurer / @Service 扫描;
- mybatis-config.xml:typeAliases、
<mappers>注册映射文件; - springmvc-servlet.xml(Web 子容器):@Controller 扫描、mvc:annotation-driven、viewResolver。
下面交互实验看加载树与顺序(对照 GuestBookSSM):
交互实验:四配置文件加载关系(SSMConfigMap)
数字是加载顺序。点击任一文件看「谁加载它、里面配了什么」。对照真实工程 GuestBookSSM(web.xml / applicationContext.xml / springmvc-servlet.xml / mybatis-config.xml)。
web.xml —— 由 Tomcat 容器启动时最先读 加载
职责:注册 ContextLoaderListener + DispatcherServlet + Filter(编码/权限)
applicationContext.xml 由 ContextLoaderListener 加载,是 Spring「根容器」(管 Service/DAO/数据源/事务);springmvc-servlet.xml 由 DispatcherServlet 加载,是「Web 子容器」(只管 Controller 与视图解析),它能看到根容器的 Bean。
关键点:applicationContext.xml 是 Spring「根容器」,springmvc-servlet.xml 是它的「Web 子容器」——子容器能看到根容器的 Bean(Service/DAO),所以 Controller 能 @Autowired 到 Service。
三、数据源与事务管理
- dataSource:连接池(如 Druid/C3P0),统一管理数据库连接;
- txManager:事务管理器,配合
@Transactional实现声明式事务; - sqlSessionFactory + MapperScannerConfigurer:MyBatis 的工厂与 Mapper 扫描。
业务方法上加 @Transactional,Spring 就会在方法执行前开启事务、正常返回时提交、抛异常时回滚——不用手写 commit/rollback。下面交互实验看事务的提交/回滚:
交互实验:事务 commit / rollback 对比(TransactionDemo)
setAutoCommit · commit/rollback转账场景:A(Tom,1000 元)转给 B(Jerry,500 元)300 元——A 扣款 + B 加款必须全成功或全失败。 选一个场景,用「下一步」逐步走查:注意已提交数据与事务内部状态两层数据何时一致、何时不同。
已提交数据(其他查询可见)
| 账号 | 户主 | 余额(元) |
|---|---|---|
| A | Tom | 1000 |
| B | Jerry | 500 |
事务内部状态(pending,未提交)
| 账号 | 户主 | 余额(元) |
|---|---|---|
| A | Tom | 1000 |
| B | Jerry | 500 |
事务走查日志
- 1con.setAutoCommit(false)关闭自动提交,事务开始:此后每条变更都是「未提交(pending)」的,只有本事务自己看得见
commit vs rollback:最终已提交数据
✅ 全部成功 → commit()
| Tom | 700 元 |
| Jerry | 800 元 |
❌ 中途失败 → rollback()
| Tom | 1000 元 |
| Jerry | 500 元 |
经典写法:try / catch + commit / rollback
con.setAutoCommit(false);
try {
// op1: A 扣款 300;op2: B 加款 300(多条 SQL)
con.commit(); // 全部成功 → 提交
} catch (SQLException e) {
con.rollback(); // 任一步失败 → 回滚到事务开始前的状态
} finally {
con.setAutoCommit(true); // 恢复自动提交(建议)
}事务要点
- 事务是一组「全成功或全失败」的操作(原子性):转账的扣款 + 加款必须一起生效,不能只做一半;
- 默认每条 SQL 自动提交;setAutoCommit(false) 关闭后,多条语句组成一个事务;
- commit() 让 pending 变更永久生效;rollback() 丢弃全部未提交变更,恢复到事务开始前的状态;
- 事务未提交前,变更只有本事务自己看得见——其他查询看到的仍是旧的已提交数据;
- 最佳实践:catch 到异常 → rollback();finally 里恢复自动提交。
四、分层调用链:Controller → Service → Mapper
一次「保存留言」请求的完整链路:
- 浏览器提交表单 → DispatcherServlet;
- Controller(@RequestMapping)接收参数,调用 Service;
- Service(@Service @Transactional)执行业务逻辑,调用 DAO;
- Mapper(@Mapper)执行 XML 里的 SQL,写入数据库;
- 结果逐层返回,Controller 把数据放进 Model,ViewResolver 渲染 JSP。
分层的好处:每层只依赖下一层的接口,替换持久层实现(MyBatis ↔ JPA)不影响上层;事务只需在 Service 层声明一次。
思考题
- Spring、SpringMVC、MyBatis 各自负责哪一层?为什么这样分工?
- applicationContext.xml 与 springmvc-servlet.xml 分别是「根容器」还是「子容器」?Controller 为什么能 @Autowired 到 Service?
@Transactional加在什么层最合适?它如何决定提交还是回滚?- sqlSessionFactory、MapperScannerConfigurer、dataSource 各自的作用是什么?
- 分层架构带来了哪些好处?
学习小测验
学习小测验
SSM 中负责「业务层」(IoC + 事务)的框架是( )
@Transactional 的作用是( )
applicationContext.xml 与 springmvc-servlet.xml 的关系是( )
一次「保存留言」请求的正确调用链是( )
sqlSessionFactory 的作用是( )
SSM 分层架构的主要好处是( )