今天针对 SSM(Spring+SpringMVC+MyBatis)框架整合展开了学习,学习内容如下:
我们在进行 JavaEE 开发时,为了实现解耦和提高开发效率,通常会采用 SSM(Spring+SpringMVC+MyBatis)框架整合的方案。
- Spring:作为核心容器,负责管理业务组件(Service)和持久层组件(DAO/Repository),并提供事务管理功能。
- SpringMVC:作为表现层框架,负责处理 HTTP 请求,接收前端参数,并返回视图或数据。
- MyBatis:作为持久层框架,负责简化数据库操作,实现对象与数据库表的映射。
SSM 框架整合的核心思路是:
- Spring 整合 MyBatis:将 MyBatis 的
SqlSessionFactory交给 Spring 容器管理,并扫描 Mapper 接口生成代理对象,让 Service 层可以直接注入 Mapper 进行使用。 - SpringMVC 的配置:配置前端控制器(DispatcherServlet)和处理器映射,处理 Web 层的请求。
1. 环境准备与依赖配置
首先,我们需要在pom.xml中引入 SSM 三大框架以及数据库驱动、连接池等必要的依赖。
注意:为了使用注解进行事务管理,我们需要引入spring-aspects依赖。
1<dependencies> 2 <!-- Spring 上下文环境 --> 3 <dependency> 4 <groupId>org.springframework</groupId> 5 <artifactId>spring-context</artifactId> 6 <version>5.3.15</version> 7 </dependency> 8 <!-- Spring 事务 --> 9 <dependency> 10 <groupId>org.springframework</groupId> 11 <artifactId>spring-tx</artifactId> 12 <version>5.3.15</version> 13 </dependency> 14 <!-- Spring JDBC --> 15 <dependency> 16 <groupId>org.springframework</groupId> 17 <artifactId>spring-jdbc</artifactId> 18 <version>5.3.15</version> 19 </dependency> 20 <!-- SpringMVC --> 21 <dependency> 22 <groupId>org.springframework</groupId> 23 <artifactId>spring-webmvc</artifactId> 24 <version>5.3.15</version> 25 </dependency> 26 27 <!-- Druid 数据源 --> 28 <dependency> 29 <groupId>com.alibaba</groupId> 30 <artifactId>druid</artifactId> 31 <version>1.2.8</version> 32 </dependency> 33 34 <!-- MySQL 驱动 --> 35 <dependency> 36 <groupId>mysql</groupId> 37 <artifactId>mysql-connector-java</artifactId> 38 <version>8.0.28</version> 39 </dependency> 40 41 <!-- MyBatis --> 42 <dependency> 43 <groupId>org.mybatis</groupId> 44 <artifactId>mybatis</artifactId> 45 <version>3.5.9</version> 46 </dependency> 47 <!-- MyBatis 与 Spring 整合包 --> 48 <dependency> 49 <groupId>org.mybatis</groupId> 50 <artifactId>mybatis-spring</artifactId> 51 <version>2.0.7</version> 52 </dependency> 53 54 <!-- Lombok --> 55 <dependency> 56 <groupId>org.projectlombok</groupId> 57 <artifactId>lombok</artifactId> 58 <version>1.18.22</version> 59 </dependency> 60</dependencies>2. 配置文件详解
SSM 整合涉及三个主要的配置文件:web.xml(Web 容器配置)、springmvc.xml(表现层配置)、applicationContext.xml(业务与持久层配置)。
2.1 web.xml 配置
这是 JavaWeb 的入口,我们需要配置 Spring 的监听器和 SpringMVC 的前端控制器。
1<web-app> 2 <!-- 配置 Spring 监听器,加载业务层配置 --> 3 <listener> 4 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 5 </listener> 6 <!-- 指定 Spring 配置文件位置 --> 7 <context-param> 8 <param-name>contextConfigLocation</param-name> 9 <param-value>classpath:applicationContext.xml</param-value> 10 </context-param> 11 12 <!-- 配置 SpringMVC 前端控制器 --> 13 <servlet> 14 <servlet-name>dispatcher</servlet-name> 15 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 16 <init-param> 17 <param-name>contextConfigLocation</param-name> 18 <param-value>classpath:springmvc.xml</param-value> 19 </init-param> 20 <load-on-startup>1</load-on-startup> 21 </servlet> 22 <servlet-mapping> 23 <servlet-name>dispatcher</servlet-name> 24 <url-pattern>/</url-pattern> 25 </servlet-mapping> 26</web-app>2.2 MyBatis 配置 (SqlMapConfig.xml)
虽然大部分配置在 Spring 中完成,但 MyBatis 的核心配置文件(如别名、插件等)仍需单独配置。
1<configuration> 2 <!-- 别名配置,对应实体类包 --> 3 <typeAliases> 4 <package name="com.xzit.entity"/> 5 </typeAliases> 6 <!-- Mapper 映射文件位置 --> 7 <mappers> 8 <package name="com.xzit.mapper"/> 9 </mappers> 10</configuration>2.3 Spring 核心配置 (applicationContext.xml)
这是整合的关键,配置了数据源、SqlSessionFactory 和 Mapper 扫描。
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:tx="http://www.springframework.org/schema/tx" 5 xsi:schemaLocation="..."> 6 7 <!-- 1. 加载数据库配置文件 --> 8 <context:property-placeholder location="classpath:db.properties"/> 9 10 <!-- 2. 组件扫描(扫描 Service 和 Repository) --> 11 <context:component-scan base-package="com.xzit"/> 12 13 <!-- 3. 配置数据源 Druid --> 14 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 15 <property name="driverClassName" value="${jdbc.driver}"/> 16 <property name="url" value="${jdbc.url}"/> 17 <property name="username" value="${jdbc.username}"/> 18 <property name="password" value="${jdbc.password}"/> 19 </bean> 20 21 <!-- 4. 配置 SqlSessionFactory --> 22 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 23 <property name="dataSource" ref="dataSource"/> 24 <property name="configLocation" value="classpath:SqlMapConfig.xml"/> 25 </bean> 26 27 <!-- 5. 配置 Mapper 扫描器,生成代理对象 --> 28 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 29 <property name="basePackage" value="com.xzit.mapper"/> 30 <!-- 如果 SqlSessionFactory 的 id 不是默认的,需要指定 --> 31 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> 32 </bean> 33 34 <!-- 6. 配置事务管理器 --> 35 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 36 <property name="dataSource" ref="dataSource"/> 37 </bean> 38 <!-- 开启注解事务 --> 39 <tx:annotation-driven transaction-manager="transactionManager"/> 40</beans>2.4 SpringMVC 配置 (springmvc.xml)
配置视图解析器和注解驱动。
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xsi:schemaLocation="..."> 6 7 <!-- 扫描控制层组件 --> 8 <context:component-scan base-package="com.xzit.controller"/> 9 10 <!-- 开启 MVC 注解驱动 --> 11 <mvc:annotation-driven/> 12 13 <!-- 配置视图解析器 (如果使用 JSP) --> 14 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 15 <property name="prefix" value="/WEB-INF/views/"/> 16 <property name="suffix" value=".jsp"/> 17 </bean> 18</beans>3. 代码实战
完成配置后,我们编写一个简单的用户管理模块来测试整合是否成功。
3.1 数据库表结构
1CREATE TABLE `user` ( 2 `id` int NOT NULL AUTO_INCREMENT, 3 `name` varchar(255) DEFAULT NULL, 4 `age` int DEFAULT NULL, 5 PRIMARY KEY (`id`) 6);3.2 实体类 (Entity)
1package com.xzit.entity; 2 3import lombok.Data; 4 5@Data 6public class User { 7 private Integer id; 8 private String name; 9 private Integer age; 10}3.3 Mapper 接口与 XML
接口:
1package com.xzit.mapper; 2 3import com.xzit.entity.User; 4import org.apache.ibatis.annotations.Mapper; 5import org.springframework.stereotype.Repository; 6 7import java.util.List; 8 9@Repository 10public interface UserMapper { 11 void save(User user); 12 User findById(Integer id); 13 List<User> findAll(); 14}UserMapper.xml (放在 resources/mapper 目录下):
1<?xml version="1.0" encoding="UTF-8" ?> 2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3<mapper namespace="com.xzit.mapper.UserMapper"> 4 <insert id="save" parameterType="User"> 5 INSERT INTO user(name, age) VALUES(#{name}, #{age}) 6 </insert> 7 <select id="findById" resultType="User"> 8 SELECT * FROM user WHERE id = #{id} 9 </select> 10 <select id="findAll" resultType="User"> 11 SELECT * FROM user 12 </select> 13</mapper>3.4 Service 层
1package com.xzit.service; 2 3import com.xzit.entity.User; 4import com.xzit.mapper.UserMapper; 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.stereotype.Service; 7import org.springframework.transaction.annotation.Transactional; 8 9import java.util.List; 10 11@Service 12@Transactional // 开启事务 13public class UserService { 14 15 @Autowired 16 private UserMapper userMapper; 17 18 public void addUser(User user) { 19 userMapper.save(user); 20 // 如果这里抛出异常,数据会回滚 21 } 22 23 public User getUserById(Integer id) { 24 return userMapper.findById(id); 25 } 26}3.5 Controller 层
1package com.xzit.controller; 2 3import com.xzit.entity.User; 4import com.xzit.service.UserService; 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.stereotype.Controller; 7import org.springframework.web.bind.annotation.*; 8 9@RestController // 等价于 @Controller + @ResponseBody 10@RequestMapping("/user") 11public class UserController { 12 13 @Autowired 14 private UserService userService; 15 16 @PostMapping("/add") 17 public String addUser(@RequestBody User user) { 18 userService.addUser(user); 19 return "success"; 20 } 21 22 @GetMapping("/{id}") 23 public User getUser(@PathVariable Integer id) { 24 return userService.getUserById(id); 25 } 26}