当前位置: 首页 > article >正文

SSM整合:Spring+SpringMVC+MyBatis完美融合实战指南

前言

在Java企业级开发领域,SSM(Spring+SpringMVC+MyBatis)框架组合一直占据着重要地位。这三个轻量级框架各司其职又相互配合,为开发者提供了高效、灵活的开发体验。本文将深入探讨SSM框架的整合过程,揭示整合背后的原理,并提供实际开发中的最佳实践,帮助开发者构建高质量的Java Web应用。

一、SSM框架概述

1.1 为什么选择SSM框架组合?

SSM框架组合在Java Web开发中广受欢迎,主要原因在于:

  • Spring:提供了全面的IoC(控制反转)和AOP(面向切面编程)功能,是整合的核心

  • SpringMVC:基于Spring的MVC框架,处理Web层请求和响应

  • MyBatis:优秀的持久层框架,简化了数据库操作

三者结合形成了清晰的分层架构:

  1. 表示层:SpringMVC处理用户交互

  2. 业务层:Spring管理业务逻辑和事务

  3. 持久层:MyBatis负责数据访问

1.2 SSM与SSH的对比

特性SSMSSH
持久层框架MyBatis(SQL更灵活)Hibernate(全自动ORM)
学习曲线相对平缓较陡峭
性能更高(直接控制SQL)较好(自动优化)
适用场景复杂SQL、高性能需求快速开发、标准CRUD

二、SSM整合详细步骤

2.1 环境准备

<!-- Maven依赖示例 -->
<dependencies><!-- Spring核心 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.18</version></dependency><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.18</version></dependency><!-- MyBatis核心 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><!-- MyBatis-Spring整合包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.7</version></dependency><!-- 数据库相关 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!-- 其他工具 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.2</version></dependency>
</dependencies>

2.2 Spring与SpringMVC整合

2.2.1 web.xml配置
<!-- web.xml核心配置 -->
<web-app><!-- 配置SpringMVC前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置Spring上下文监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 指定Spring配置文件位置 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-context.xml</param-value></context-param>
</web-app>
2.2.2 父子容器关系
  • 父容器:由ContextLoaderListener创建,加载service、dao等bean

  • 子容器:由DispatcherServlet创建,加载controller等web相关bean

  • 特点:子容器可以访问父容器的bean,但父容器不能访问子容器的bean

2.3 Spring与MyBatis整合

2.3.1 数据源配置
<!-- spring-context.xml中数据源配置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/ssm_demo?useSSL=false&amp;serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="123456"/><!-- 连接池配置 --><property name="initialSize" value="5"/><property name="maxActive" value="20"/><property name="maxWait" value="60000"/>
</bean>
2.3.2 SqlSessionFactory配置
<!-- MyBatis SqlSessionFactory配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><!-- 指定MyBatis全局配置文件 --><property name="configLocation" value="classpath:mybatis-config.xml"/><!-- 指定mapper.xml文件位置 --><property name="mapperLocations" value="classpath:mapper/*.xml"/><!-- 配置别名包 --><property name="typeAliasesPackage" value="com.example.entity"/>
</bean>
2.3.3 Mapper接口扫描
<!-- Mapper接口扫描配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.example.dao"/><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

2.4 事务管理配置

<!-- 事务管理器配置 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean><!-- 注解驱动的事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/><!-- 事务增强配置(可选) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="save*" propagation="REQUIRED"/><tx:method name="add*" propagation="REQUIRED"/><tx:method name="update*" propagation="REQUIRED"/><tx:method name="delete*" propagation="REQUIRED"/><tx:method name="get*" read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="*" propagation="REQUIRED"/></tx:attributes>
</tx:advice>

三、SSM整合高级技巧

3.1 多数据源配置

@Configuration
public class DataSourceConfig {@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DruidDataSourceBuilder.create().build();}@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DruidDataSourceBuilder.create().build();}@Bean@Primarypublic DynamicDataSource dataSource(@Qualifier("primaryDataSource") DataSource primaryDataSource,@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("primary", primaryDataSource);targetDataSources.put("secondary", secondaryDataSource);DynamicDataSource dataSource = new DynamicDataSource();dataSource.setTargetDataSources(targetDataSources);dataSource.setDefaultTargetDataSource(primaryDataSource);return dataSource;}
}

3.2 MyBatis分页插件集成

<!-- 配置分页插件 -->
<bean id="pageInterceptor" class="com.github.pagehelper.PageInterceptor"><property name="properties"><value>helperDialect=mysqlreasonable=truesupportMethodsArguments=trueparams=count=countSqlautoRuntimeDialect=true</value></property>
</bean><!-- 将插件添加到MyBatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 其他配置... --><property name="plugins"><array><ref bean="pageInterceptor"/></array></property>
</bean>

3.3 全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);@ExceptionHandler(Exception.class)@ResponseBodypublic Result handleException(HttpServletRequest request, Exception e) {logger.error("请求地址:" + request.getRequestURL(), e);if (e instanceof BusinessException) {return Result.error(e.getMessage());} else if (e instanceof NoHandlerFoundException) {return Result.error(404, "接口不存在");} else {return Result.error("服务异常");}}
}

四、SSM整合常见问题与解决方案

4.1 常见问题排查

  1. Bean创建异常

    • 检查包扫描路径是否正确

    • 检查依赖注入是否正确(@Autowired或@Resource)

    • 查看是否有循环依赖

  2. 事务不生效

    • 确保方法为public

    • 检查是否在同一个类中调用

    • 确认是否抛出RuntimeException

  3. MyBatis映射问题

    • 检查mapper.xml中namespace是否正确

    • 确认SQL语句是否正确

    • 检查resultMap配置

4.2 性能优化建议

  1. MyBatis一级缓存与二级缓存

    • 合理使用一级缓存(SqlSession级别)

    • 谨慎启用二级缓存(Mapper级别),考虑数据一致性

  2. SQL优化

    • 使用MyBatis的懒加载

    • 避免N+1查询问题

    • 合理使用索引

  3. 连接池配置优化

    • 根据并发量调整连接池大小

    • 设置合理的超时时间

    • 定期监控连接池状态

五、从SSM到Spring Boot的演进

虽然SSM组合非常强大,但随着Spring Boot的兴起,开发方式正在发生变化:

特性SSMSpring Boot
配置方式XML为主约定优于配置,注解为主
依赖管理手动管理Starter依赖自动管理
部署方式需要外部容器内嵌容器,可执行JAR
开发效率中等
适用场景传统企业项目微服务、快速开发项目

对于新项目,推荐考虑Spring Boot + MyBatis组合,它保留了MyBatis的灵活性,同时享受Spring Boot的开发便利。

结语

SSM框架整合是Java Web开发的重要技能,通过本文的学习,相信你已经掌握了SSM整合的核心要点和高级技巧。在实际项目中,要根据业务需求灵活调整配置,并持续关注性能优化。技术不断演进,但分层架构和模块化设计的思想永远不会过时。

思考题:在你的项目中,SSM框架遇到了哪些挑战?是如何解决的?欢迎在评论区分享你的经验!

相关文章:

SSM整合:Spring+SpringMVC+MyBatis完美融合实战指南

前言 在Java企业级开发领域&#xff0c;SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架组合一直占据着重要地位。这三个轻量级框架各司其职又相互配合&#xff0c;为开发者提供了高效、灵活的开发体验。本文将深入探讨SSM框架的整合过程&#xff0c;揭示整合背后的原…...

Spring Boot分页查询进阶:整合Spring Data REST实现高效数据导航

目录&#xff1a; 引言分页查询基础回顾 2.1 Spring Data JPA分页接口 2.2 Pageable与Page的使用 2.3 常见分页参数设计Spring Data REST简介 3.1 HATEOAS与超媒体驱动API 3.2 Spring Data REST核心功能 3.3 自动暴露Repository接口整合Spring Boot与Spring Data REST 4.1 项目…...

阿里云 Serverless 助力海牙湾构建弹性、高效、智能的 AI 数字化平台

作者&#xff1a;赵世振、十眠、修省 “通过阿里云 Serverless 架构&#xff0c;我们成功解决了弹性能力不足、资源浪费与运维低效的痛点。SAE 的全托管特性大幅降低技术复杂度。未来&#xff0c;我们将进一步探索 Serverless 与 AI 的结合&#xff0c;为客户提供更智能的数字…...

升级node@22后运行npm install报错 distutils not found

从node20升级到node22后&#xff0c;在运行 npm install 的时候报了很多 gyp 错误&#xff0c;其中包括 npm error npm error ModuleNotFoundError: No module named distutils。 问题原因是我在使用 brew install node22 的过程中自动把 python 升级到了 3.13。而 distutils …...

一个开源的多播放源自动采集在线影视网站

这里写自定义目录标题 欢迎使用Markdown编辑器GoFilm简介项目部署1、前置环境准备1.2 redis 配置 film-api 后端服务配置将 GoFilm 项目根目录下的 film 文件夹上传到 linux 服务器的 /opt 目录下 2. 构建运行1. docker 部署1.1 安装 docker , docker compose 环境 注意事项: 2…...

【PhysUnits】10 减一操作(sub1.rs)

一、源码 代码实现了一个类型级别的减一操作(Sub1 trait)&#xff0c;通过Rust的类型系统在编译期完成数值减一的计算。 //! 减一操作特质实现 / Decrement operation trait implementation //! //! 提供类型级别的减一计算 / Provides type-level decrement operationuse su…...

深度检测与动态透明度控制 - 基于Babylon.js的遮挡检测实现解析

首先贴出实现代码&#xff1a; OcclusionFader.ts import { AbstractEngine, Material, type Behavior, type Mesh, type PBRMetallicRoughnessMaterial, type Scene } from "babylonjs/core"; import { OcclusionTester } from "../../OcclusionTester"…...

Linux下使用socat将TCP服务转为虚拟串口设备

Linux下使用socat将TCP服务转为虚拟串口设备 socat是一个强大的网络工具&#xff0c;可以将TCP连接转换为虚拟串口设备&#xff0c;这在嵌入式开发、工业控制等领域非常有用。下面详细介绍如何实现这一功能。 基本原理 socat可以通过创建伪终端(PTY)来模拟串口设备&#xff…...

docker push 报错 denied: requested access to the resource is denied

问题&#xff1a;当 docker logout -> docker login 用户登录&#xff0c;但仍然无法 docker push $ docker push <username>/nginx-custom:v1 The push refers to repository [docker.io/jagger/nginx-custom] 340e6d3ea0c7: Preparing 941dd9dd8ee4: Preparing f6…...

epub→pdf | which 在线转换??好用!!

1、PDF派&#xff08;free&quick) pdf转word_pdf转换成excel_pdf转换成ppt _纬来PDF转换器 评价&#xff1a;目前使用免费&#xff0c;转化的时候有进度条提示&#xff0c;总的来说比较快&#xff0c;50mb的文件在40秒内可以转换完成&#xff0c;推荐 2、pdfconvert(free…...

PBX、IP PBX、FXO 、FXS 、VOIP、SIP 的概念解析以及关系

PBX&#xff08;Private Branch Exchange&#xff09; 概念 &#xff1a;PBX 是专用交换机&#xff0c;是一种在企业或组织内部使用的电话交换系统。它允许内部用户之间以及内部用户与外部公共电话网络&#xff08;PSTN&#xff09;之间进行通信。例如&#xff0c;在一个大型企…...

MySQL数据高效集成到金蝶云星空的技术分享

MySQL数据集成到金蝶云星空的技术案例分享&#xff1a;SR新建调拨单内部供应商-深圳天一 在企业信息化系统中&#xff0c;数据的高效流动和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例——将MySQL中的数据集成到金蝶云星空&#xff0c;以支持…...

git 命令之-git cherry-pick

今天得到一个通知&#xff0c;这个业务版本里面部分已经开发但还没测试的内容要新开一个分支提交&#xff0c;但是我已经有几个提交上去了&#xff0c;难道只能一个一个文件复制到新的分支吗&#xff1f;我不&#xff0c;我找到了这个git命令&#xff0c;可以解决我的困惑&…...

如何在STM32CubeMX下为STM32工程配置调试打印功能

为STM32工程配置调试打印功能 一、配置调试用的打印串口 #include <stdio.h> //标准输入输出库//1.在STM32CubeMX中打开并配置好某串口设备&#xff1b; //2.在main.c文件中添加如下代码行对输入输出重定向&#xff1b; //3.在文件开头包含stdio.h头文件。 #pragma im…...

Linux系统 - 基本概念

介绍一些Linux系统的基本概念 1 操作系统的核心—内核 “操作系统”通常包含两种不同含义。 1&#xff0e;指完整的软件包&#xff0c;这包括用来管理计算机资源的核心层软件&#xff0c;以及附带的所有标准软件工具&#xff0c;诸如命令行解释器、图形用户界面、文件操作工具…...

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器 js 代码 其他地方用直接导入js getCurrentUserId 这是自己后端获取 域账号地址 我是成功返回200 //true普通浏览器 fasle 无痕浏览器 export const checkBrowserMode async () > {try {const response a…...

在h5端实现录音发送功能(兼容内嵌微信小程序) recorder-core

本文将通过一个实际的 Vue3 组件示例&#xff0c;带你一步步实现“按住录音&#xff0c;松开发送&#xff0c;上滑取消”的语音录制功能。 我们将使用强大且小巧的开源库 recorder-core&#xff0c;支持 MP3、WAV、AAC 等编码格式&#xff0c;兼容性较好。 &#x1f527; 项目…...

PDF电子发票数据提取至Excel

声明&#xff1a;本软件是吾爱大佬th4c3y原创&#xff0c;本人只是搬运工&#xff01; 发票识别更新记录 【2025-3-14】更新 v2.0 在字段设置中新增自定义字段&#xff08;仅在 PDF 正则式接口下生效&#xff09;&#xff0c;支持自定义正则表达式或固定字符。 自定义字段会…...

【身份证识别表格】把大量手机拍摄的身份证信息转换成EXCEL表格的数据,拍的身份证照片转成excel表格保存,基于WPF和腾讯OCR的实现方案

基于WPF和腾讯OCR的身份证照片转Excel方案 应用场景 ​​企业人事管理​​&#xff1a;新员工入职时批量录入数百份身份证信息&#xff0c;传统手动录入易出错且耗时。通过OCR自动提取姓名、身份证号等字段&#xff0c;生成结构化Excel表格&#xff0c;效率提升10倍以上。 ​​…...

FPGA高速接口 mipi lvds cameralink hdml 千兆网 sdi

mipi: https://blog.csdn.net/SDJ_success/article/details/146541776 cameralink CameraLink协议 CameraLink协议是一种专门针对机器视觉应用领域的串行通信协议&#xff0c;它使用低压差分信号(LVDS)进行数据的传输和通信。CameraLink标准是在ChannelLink标准的基础上多加了…...

Linux路径解析指南:逻辑路径 vs 实际路径详解

在 Linux 系统中&#xff0c;逻辑路径&#xff08;Logical Path&#xff09;和 实际路径&#xff08;Physical Path&#xff09;是两个不同的概念&#xff0c;主要区别在于它们如何解析文件或目录的位置。以下是详细解释&#xff1a; 目录 1. 逻辑路径&#xff08;Logical Path…...

Azure 公有云基础架构与核心服务:从基础到实践指南

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 Azure 的基础架构由多个核心组件构成&#xff0c;理解这些概念是掌握其技术框架的第一步&#xff1a; 地理区域&#xff08;Geographic R…...

【运维_日常报错解决方案_docker系列】一、docker系统不起来

今天忽然想起来哎&#xff0c;还有一台”尘封“着的服务器&#xff0c;好久没用了&#xff0c;就随便打开登了登&#xff0c;然后想看一下服务器上面还有正在跑着的容器服务吗&#xff0c;然后使用docker ps 发现报错了。 然后重启也是下面这个状态。 查看docker状态&#xf…...

C# 数组与字符串:全面解析与应用实践

在C#编程语言中&#xff0c;数组和字符串是两种最基础也是最重要的数据类型。无论是简单的控制台应用程序&#xff0c;还是复杂的企业级系统&#xff0c;数组和字符串都扮演着不可或缺的角色。本文将全面深入地探讨C#中数组和字符串的特性、使用方法、性能考量以及实际应用场景…...

前端vue中使用signalr

一、引入SignalR库 使用NPM引入SignalR库 npm install @microsoft/signalrJs文件中引入 import * as signalR from @microsoft/signalr;二、初始化连接 这一步需要指定SignalR Hub的URL。 const connection = new signalR.HubConnectionBuilder().withUrl("https://y…...

Stable Diffusion底模对应的VAE推荐

以下是主流Stable Diffusion底模对应的VAE推荐表格&#xff1a; 底模版本推荐VAE类型说明SD1.5SD1.5专用VAE通常使用vae-ft-mse-840000-ema-pruned.safetensorsSD2.0SD1.5兼容VAE或SD2专用VAE部分SD2模型需配套512-ema-only.vae.ptSD3内置VAESD3系列模型通常自带集成VAE无需额…...

centos7.5安装kubernetes1.25.0

centos7.5安装kubernetes centos7.5kubernetes1&#xff09;准备阶段准备2台虚拟机配置静态IP修改主机名桥接设置配置阿里云的repo源配置k8s切国际源配置时间同步安装基础软件包 2)安装containerd服务安装配置开启启动 3)安装k8s4)安装kubersphere下载helm安装包解压将helm配置…...

‌AT2659S射频前端芯片技术解析:L1频段低噪声高增益GNSS信号放大

以下是关于‌AT2659S L1频段卫星导航射频前端芯片‌的客观描述&#xff0c;严格基于用户提供的原始信息&#xff0c;采用分享式表述&#xff0c;保持参数和核心内容不变&#xff1a; AT2659S芯片概述‌ AT2659S是一款基于SiGe工艺的射频前端芯片&#xff0c;专为L1频段&#…...

ROS2学习(15)------ROS2 TF2 机器人坐标系管理器

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 ROS版本&#xff1a;2 在 ROS 2 中&#xff0c;TF2&#xff08;Transform Library, v2&#xff09; 是一个非常核心的工具库&#xff0c;用于管理多个坐标系之间的 变换关系&#xff08;tran…...

每日c/c++题 备战蓝桥杯(洛谷P3382 三分法求极值详解)

洛谷P3382 三分法求极值详解 题目描述 P3382 三分法 要求在给定区间内寻找一个多项式函数的最大值点。题目保证函数在区间内先严格递增后严格递减&#xff08;单峰函数&#xff09;&#xff0c;适合使用三分法求解。 算法原理 三分法核心思想 对于单峰函数&#xff0c;在区…...